java 如何确定 BufferedOutputStream 的 write 方法的缓冲区大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9994110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to determine the buffer size for BufferedOutputStream's write method
提问by Ahamed
I am trying to copy a file using the following code:
我正在尝试使用以下代码复制文件:
1:
1:
int data=0;
byte[] buffer = new byte[4096];
while((data = bufferedInputStream.read())!=-1){
bufferedOutputStream.write(data);
}
2:
2:
byte[] buffer = new byte[4096];
while(bufferedInputStream.read(buffer)!=-1){
bufferedOutputStream.write(buffer);
}
Actual size of file is 3892028 bytes(on windows). The file will be uploaded by the user thro struts2 fileupload. Uploaded file size is exactly same as that of windows. When I try to copy the uploaded file from temporary folder, the copied file varies in size and the time taken also varies(it is negligible). Please find the below readings.
文件的实际大小为 3892028 字节(在 Windows 上)。该文件将由用户通过 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
If I increase the buffer size further, time taken increases, again it is negligible. So my questions are,
如果我进一步增加缓冲区大小,花费的时间也会增加,同样可以忽略不计。所以我的问题是,
- Why the file size changes?
- Is there any subtle consequences due to this size variation?
- What is the best way to accomplish this functionality(copying a file)?
- 为什么文件大小会改变?
- 由于这种尺寸变化,是否有任何微妙的后果?
- 完成此功能(复制文件)的最佳方法是什么?
I don't know what is going beneath? Thanks for any suggestion. Edit:I have flush() and close() method calls. Note:I have trimmed my code to make it simpler.
不知道下面是什么情况?感谢您的任何建议。 编辑:我有 flush() 和 close() 方法调用。 注意:我已经修剪了我的代码以使其更简单。
回答by bezmax
The problem is, BufferedInputStream.read(byte[])
reads as much as it can into the buffer. So if the stream contains only 1 byte, only the first byte of byte array will be filled. However, BufferedInputStream.write(byte[])
writes allthe given bytes into the stream, meaning it will still write full 4096 bytes, containing 1 byte from current iteration and 4095 remaining bytes from previous iteration.
问题是,BufferedInputStream.read(byte[])
尽可能多地读取缓冲区。因此,如果流仅包含 1 个字节,则只会填充字节数组的第一个字节。但是,BufferedInputStream.write(byte[])
将所有给定的字节写入流中,这意味着它仍将写入完整的 4096 个字节,其中包含来自当前迭代的 1 个字节和来自前一次迭代的剩余 4095 个字节。
What you need to do, is save the amount of bytes that were read, and then write the same amount.
您需要做的是保存读取的字节数,然后写入相同数量的字节。
Example:
例子:
int lastReadCnt = 0;
byte[] buffer = new byte[4096];
while((lastReadCnt = bufferedInputStream.read(buffer))!=-1){
bufferedOutputStream.write(buffer, 0, lastReadCnt);
}
References:
参考:
回答by Tomasz Nurkiewicz
- Why the file size changes?
- 为什么文件大小会改变?
Also you should pass the number of bytes read to write
method:
您还应该将读取的字节数传递给write
方法:
bufferedOutputStream.write(data, 0, bytesRead);
- What is the best way to accomplish this functionality(copying a file)?
- 完成此功能(复制文件)的最佳方法是什么?
Both from apache-commonsIO.
两者都来自apache-commonsIO。