【问题标题】:Why should we use OutputStream.write(byte[] b, int off, int len) instead of OutputStream.write(byte[] b)?为什么我们应该使用 OutputStream.write(byte[] b, int off, int len) 而不是 OutputStream.write(byte[] b)?
【发布时间】:2018-01-09 04:50:38
【问题描述】:

对不起,各位。这是一个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 类的一部分,用于使用 java.io 和 java.net.Socket 将文件从客户端发送到服务器。

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

os.write(buffer, 0, len)

而不是

os.write(buffer)

换一种方式来问这个问题:“OutputStream.write()”方法有一个“len”参数有什么意义?

似乎两个代码都运行良好。

【问题讨论】:

    标签: java-io fileoutputstream


    【解决方案1】:
    while((len=fis.read(buffer)) != -1){
        os.write(buffer, 0, len);
    }
    

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

    似乎两个代码都运行良好。

    不,他们不是。

    【讨论】:

      【解决方案2】:

      它实际上并没有以同样的方式工作。

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

      原因是您创建了一个大小为 1024 的字节数组,但您没有太多数据可以放入(或读取())到该字节数组中。因此,字节数组已满,末尾部分为 NULL。在写入文件时,这些 NULL 仍会写入文件并在 Windows 记事本中显示为空格“”...

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

      【讨论】:

      • 它们只会在第一次读取时为空,如果它很短。之后,它们可以是任何东西,即上次阅读留下的垃圾。
      猜你喜欢
      • 2014-10-08
      • 1970-01-01
      • 2011-06-13
      • 2020-07-11
      • 2010-10-30
      • 1970-01-01
      • 2014-04-23
      • 2015-01-23
      相关资源
      最近更新 更多