About me

我的照片
目前就职于杭州某电子商务公司,工作兴趣包括高并发分布式架构,JVM性能优化等方面。

2012年5月10日星期四

FileOutputStream internals

最近了解到linux上的IO库函数都是用了缓冲,分为行缓冲与全缓冲。缓冲满了才真正做系统调用。
参考:

  http://stackoverflow.com/questions/8509700/c-standard-i-o-vs-unix-i-o-basics
  http://www.groad.net/bbs/simple/?t3582.html


由此联想到java的FileOutputStream是如何做的呢?他的native代码是否也调用libc来实现的?如果是的话,应该也使用到了行缓冲。于是我写了一个代码来验证。


// Test.java
import java.io.File;
import java.io.FileOutputStream;
public class Test {
    public static void main(String[] args) throws Exception {
        File file = File.createTempFile("aaa", ".bbb");
        FileOutputStream fout = new FileOutputStream(file);
        for (;;) {
            fout.write('n');
            fout.write('i');
            fout.write('h');
            fout.write('a');
            fout.write('o');
            fout.write('\n');
        }
    }
}

运行后通过strace观察系统调用。strace -p pid -f -tt -o Test.strace. 



1195  14:31:55.405610 write(9, "n", 1 <unfinished ...>
1195  14:31:55.405663 <... write resumed> ) = 1
1195  14:31:55.409621 write(9, "i", 1)  = 1
1195  14:31:55.412765 write(9, "h", 1)  = 1
1195  14:31:55.416848 write(9, "a", 1)  = 1
1195  14:31:55.420989 write(9, "o", 1)  = 1
1195  14:31:55.424093 write(9, "\n", 1) = 1
1195  14:31:55.427213 write(9, "n", 1)  = 1
1195  14:31:55.430317 write(9, "i", 1)  = 1
1195  14:31:55.433394 write(9, "h", 1)  = 1
1195  14:31:55.436508 write(9, "a", 1)  = 1
1195  14:31:55.439966 write(9, "o", 1)  = 1
1195  14:31:55.443733 write(9, "\n", 1) = 1
1195  14:31:55.447882 write(9, "n", 1)  = 1


结果说明FileOutputStream的native代码没有做任何缓冲,而是直接调用了os的write函数。