开发者

JAVA BufferedOutputStream flush slow with correct filesize

I am using a BufferedOutputStream to write to a file. While debugging I noticed that the flush operation takes very long even if开发者_开发知识库 the OS shows that the file has got the final size.

My theory: The BufferedOutputStream tell the OS to reserve space in advance? So the OS already shows the file with the full filesize even if the BufferedOutputStream hasn't flushed completly?

Is that correct?


BufferedOutputStream maintains its own internal byte[] buffer. Looking at an implementation of the code, it just fills that buffer before writing it to the underlying stream. The documentation doesn't give much more help.

I don't think you can make any more assumptions than this without looking at the native implementations on each platform. If you wanted to get more details, you could run something like strace and inspect what's happening for a simple program.

I wrote the following simple program

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]);
        }
    }
}

And ran strace on it. Make sure you use the -f flag to keep track of child processes. A filtered copy of what ran is shown below.

[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

I don't see any calls to reserve space up front (note entirely sure about mprotect but it doesn't seem relevant). The behaviour I see on my Linux box is simply a buffer being filled and written to disk.


Is it the case that your filesystem is remote and as such the call to flush passes the data through the network (and the host on the other side might decide to actually "reserve" the file space required as you put it and only write the bytes to disk once it has received all the bytes)? Or are you using a local filesystem?


Check your virus scanner. Sometimes that slows down file writes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜