此行会将所有的“剩余”的字节,即使只有一个字节被读取,并且还可能写的东西,如果read
返回-1信号输入端:
bufferedOutputStream.write(buffer, totalBytesRead, bytesRemaining);
要只写入读取的字节,传递读取的字节数作为第三个参数。
int bytesRead = bufferedInputStream.read(buffer, totalBytesRead, bytesRemaining);
if (bytesRead == -1) {
break;
} else {
bufferedOutputStream.write(buffer, totalBytesRead, bytesRead);
totalBytesRead += bytesRead;
}
虽然没有理由为什么第二个代码应该阻止,而这个不是。
另外请注意,这种方式您正在创建您正在传输的数据的内存副本,这可能会占用大量内存,或者如果缓冲区不够大,则会使程序失败,并返回ArrayIndexOutOfBoundsException
。如果这不是你的意图,那么在读写时应该使用0
而不是totalBytesRead
作为数组偏移量,并将读取的字节数限制为缓冲区的大小。这些转换后的代码应该是这样的:
int bytesRead = bufferedInputStream.read(buffer);
if (bytesRead == -1) {
break;
} else {
bufferedOutputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
正如你所看到的,它几乎等同于你的第二个例子,你说的“块”。
在这两种情况下,偏移参数都是错误的,并且会导致它们用于抛出'ArrayIndexOutOfBoundsException'的方法。 – EJP
是否发生这取决于缓冲区的大小。如果OP想要获取内存中读取和写入数据的副本,则可以这样做。但必须小心*创建足够大的缓冲区以保存传输的数据。 – Joni
是否发生这种情况取决于缓冲区的大小*和文件的大小。使用'totalBytesRead'而不是零,这只是缓冲区中以前字节的大量浪费。给定一个足够大的文件,代码变得完全不可行,除非你使用整个缓冲区,通过零偏移量。捍卫这一点毫无意义,这只是错误的,而OP代码中的另一个错误应该是被挑选出来的。 – EJP