为什么我们应该使用 OutputStream.write(byte[] b, int off, int len) 而不是 OutputStream.write(byte[] b)?

Why should we use OutputStream.write(byte[] b, int off, int len) instead of OutputStream.write(byte[] b)?

对不起,各位。这是一个 Java 初学者的问题,但我认为它会对很多 java 学习者有所帮助。

FileInputStream fis = new FileInputStream(file);
OutputStream os = socket.getOutputStream();    
byte[] buffer = new byte[1024];
int len;
while((len=fis.read(buffer)) != -1){
    os.write(buffer, 0, len);
}

上面的代码是 FileSenderClient class 的一部分,它用于使用 java.io 和 java.net.Socket.

从客户端向服务器发送文件

我的问题是:在上面的代码中,为什么要使用

os.write(buffer, 0, len)

而不是

os.write(buffer)

以另一种方式问这个问题:"OutputStream.write()" 方法有一个 "len" 参数有什么意义?

似乎两个代码都工作正常。

它实际上不是以同样的方式工作的。

很可能您使用了非常小的文本文件进行测试。但是如果你仔细看,你还是会发现你收到的文件末尾有很多多余的空格,而且你收到的文件比你发送的文件大。

原因是您创建了一个大小为 1024 的字节数组,但没有那么多数据要放入(或读取())到该字节数组中。因此,字节数组已满,最后部分为 NULL。当写入文件时,这些 NULL 仍然写入文件并在 Windows 记事本中显示为空格 " "...

如果您使用 Notepad++ 或 Sublime Text 等高级文本编辑器查看您收到的文件,您将看到这些 NULL 字符。

while((len=fis.read(buffer)) != -1){
    os.write(buffer, 0, len);
}

因为你只想写入你实际读取的数据。考虑输入由 N 个缓冲区加一个字节组成的情况。如果没有 len 参数,您将写入 (N+1)*1024 字节而不是 N*1024+1 字节。还要考虑从套接字读取的情况,或者实际上是读取的一般情况:InputStream.read() 的实际约定是它传输至少一个字节, 而不是它填充的 缓冲区。通常它不能,出于某种原因。

It seems both codes are working fine.

不,他们不是。