如何确定BufferedOutputStream的write方法的缓冲区大小

时间:2012-04-03 13:19:01

标签: java file copy buffer

我正在尝试使用以下代码复制文件:

1:

        int data=0;
        byte[] buffer = new byte[4096];
        while((data = bufferedInputStream.read())!=-1){
            bufferedOutputStream.write(data);
        }

2:

        byte[] buffer = new byte[4096];
        while(bufferedInputStream.read(buffer)!=-1){
            bufferedOutputStream.write(buffer);
        }

文件的实际大小为3892028字节(在Windows上)。该文件将由用户thro struts2 fileupload上传。上传的文件大小与Windows完全相同。当我尝试从临时文件夹复制上传的文件时,复制的文件大小不一,所用时间也各不相同(可忽略不计)。请查看以下读物。

Without using buffer(Code 1)
Time taken 77
3892028
3891200

Buffer size 1024(Code 2)
Time taken 17
3892028
3891200

Buffer size 4096(Code 2)
Time taken 18
3892028
3891200

Buffer size 10240(Code 2)
Time taken 14
3892028
3901440

Buffer size 102400(Code 2)
Time taken 9
3892028
3993600

如果我进一步增加缓冲区大小,则所花费的时间会增加,而且可以忽略不计。所以我的问题是,

  1. 为什么文件大小会发生变化?
  2. 由于这种尺寸变化会有任何微妙的后果吗?
  3. 完成此功能的最佳方法是什么(复制文件)?
  4. 我不知道下面会发生什么?谢谢你的任何建议。 编辑:我有flush()和close()方法调用。 注意:我修剪了我的代码,使其更简单。

2 个答案:

答案 0 :(得分:10)

问题是,BufferedInputStream.read(byte[])尽可能多地读入缓冲区。因此,如果流只包含1个字节,则只填充字节数组的第一个字节。但是,BufferedInputStream.write(byte[])将给定字节的全部写入流中,这意味着它仍将写入完整的4096个字节,包含当前迭代的1个字节和前一次迭代的4095个剩余字节。

您需要做的是保存读取的字节数,然后写入相同的数量。

示例:

int lastReadCnt = 0;
byte[] buffer = new byte[4096];
while((lastReadCnt = bufferedInputStream.read(buffer))!=-1){
    bufferedOutputStream.write(buffer, 0, lastReadCnt);
}

<强>参考文献:

答案 1 :(得分:5)

  
      
  1. 为什么文件大小会发生变化?
  2.   
<德尔> 你忘了`flush()`(和`close()`):     bufferedOutputStream.flush()

此外,您应该将读取的字节数传递给write方法:

bufferedOutputStream.write(data, 0, bytesRead);
  
      
  1. 完成此功能的最佳方法是什么(复制文件)?
  2.   

来自 IO。