JDK7 Files.copy

3
在OpenJDK7项目java.nio.file.Files中,有以下函数。我的问题是,while循环条件应该是>=而不是>吗?这是因为source.read javadoc说当到达EOF时,它将返回-1而不是0。
/**
 * Reads all bytes from an input stream and writes them to an output stream.
 */
private static long copy(InputStream source, OutputStream sink)
    throws IOException
{
    long nread = 0L;
    byte[] buf = new byte[BUFFER_SIZE];
    int n;
    while ((n = source.read(buf)) > 0) {
        sink.write(buf, 0, n);
        nread += n;
    }
    return nread;
}
3个回答

1
您正在查看错误的读取函数。 InputStream 的读取函数采用字节数组作为参数,将返回已复制到缓冲区中的字节数。因此,您可以知道可以从中复制多少字节。
 * @return     the total number of bytes read into the buffer, or
 *             <code>-1</code> if there is no more data because the end of
 *             the stream has been reached.

因此,它涵盖了两种情况:流结束(-1)或由于任何其他原因未将字节读入缓冲区。


该函数的javadoc说明称它将从输入流中读取所有字节。如果在连接质量较差的情况下,下一个字节可能无法立即获取,则while循环将在获取所有字节之前结束。是这样吗? - tanyehzheng
@tanyehzheng 这是不正确的。InputStream.read 的 javadocs 表示至少会返回一个字节,否则它将会阻塞。如果由于 EOF 以外的任何原因无法读取第一个字节,则会抛出 IOException。任何返回此函数值为 0 的流都是错误的,并且没有正确地继承 InputStream。(除了缓冲区是零长度数组的情况)。 - Brian

1

这是否是一个错误,取决于该函数的意图。

通常情况下,它会像您预期的那样工作,因为对read的调用将会一直阻塞,直到有至少一个字节的数据可用。然而,如果输入流是非阻塞的,则当当前没有更多可用数据时,read调用将会返回0。这种状态与流被主动关闭不同。

换句话说,这可能是一个错误或不是,这取决于在调用该方法时面对无可用数据的非阻塞流时,您期望它执行什么操作。


如果将条件更改为">= 0",那么无论是在阻塞模式还是非阻塞模式下,它都会按预期工作。不是吗? - tanyehzheng
这取决于你的期望。你希望在没有更多数据可用时阻塞吗?而且,如果你这样做并且流是非阻塞的,你会在等待下一个数据字节时消耗100%的CPU。那不太好。 - Elias Mårtenson

1

同样的,因为这里的InputStream.read(byte[])不会返回0。来自javadoc

至少读取一个字节


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接