我正在使用BufferedOutputStream来写入文件。在调试时我注意到即使操作系统显示文件已达到最终大小,刷新操作也需要很长时间。
我的理论: BufferedOutputStream告诉操作系统提前预留空间?因此即使BufferedOutputStream没有完全刷新,操作系统也已经显示了包含完整文件大小的文件?
这是对的吗?
答案 0 :(得分:2)
BufferedOutputStream
维护自己的内部byte[]
缓冲区。查看implementation of the code,它会在将其写入基础流之前填充该缓冲区。 documentation没有提供更多帮助。
如果不查看每个平台上的本机实现,我认为你不能做出比这更多的假设。如果您想获得更多详细信息,可以运行类似strace的内容并检查简单程序的情况。
我写了以下简单程序
import java.io.*;
public class Test {
public static void main(String args[]) throws Exception {
File f = new File("test.txt");
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos, 16384);
for (int i=0;i<10000;++i) {
bos.write(new byte[1024]);
}
}
}
并在其上运行strace
。确保使用-f
标志来跟踪子进程。下面显示了已运行内容的过滤副本。
[pid 6394] mprotect(0x7fdebc03e000, 4096, PROT_READ|PROT_WRITE) = 0
[pid 6394] open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
[pid 6394] fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid 6394] mprotect(0x7fdebc03f000, 16384, PROT_READ|PROT_WRITE) = 0
[pid 6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"..., 16384) = 16384
[pid 6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"..., 16384) = 16384
[pid 6394] write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\"..., 16384) = 16384
我没有看到任何预先预留空间的电话(注意完全确定mprotect,但它似乎并不相关)。我在Linux机器上看到的行为只是填充并写入磁盘的缓冲区。
答案 1 :(得分:0)
是不是你的文件系统是远程的,因此对flush的调用会通过网络传递数据(而另一方的主机可能会决定实际“保留”所需的文件空间,并且只有收到所有字节后,将字节写入磁盘)?或者您使用的是本地文件系统?
答案 2 :(得分:0)
检查您的病毒扫描程序。有时会减慢文件写入速度。