IO buffer 1970-01-01 00:00

同事:为什么代码里面的输出,在log文件里面没看到呢?

我:你用的是print,不是用logging输出的日志吧。

同事:是的。

我:你改成用logging输出。

看过《UNIX环境高级编程》的同学应该知道,标准I/O库是带缓存的I/O,目的是减少调用read和write的次数。

典型的以空间换时间思维。:)

输入流、输出流默认都是有buffer,错误流默认是unbuffer。如果输出流是到终端,默认是line buffer。

无缓存IO操作数据流向路径:数据——内核缓存区——磁盘
标准IO操作数据流向路径:数据——流缓存区——内核缓存区——磁盘

通过下面的程序验证一下:

运行命令是: test.py | cat

1
2
3
4
5
6
#!/usr/bin/env python
import time

while 1:
    print "hello,world"
    time.sleep(1)

如果我要在cat命令后面实时看到输出怎么办呢?用fflush清空buffer或者调用setvbuf来设置buffer大小。

Python中你可以用sys.stdout.flush()来清空print的buffer。

当然你可以用不带buffer的write函数。

#include <stdio.h>
#include <stdlib.h>

int main(){

    while (1){
            write(1, "hello,world\n", sizeof("hello,world\n"));
            sleep(1);
    }
    return 0;
}

shell命令也经常会碰到buffer的问题。比如上面的C程序编译后,我用下面的命令运行:

./a.out | grep -a 'h' | grep 'h'

是没有任何输出的(除非buffer被塞满了)。因为第一个grep的输出被buffer了。给第一个grep带上--line-buffered即可。

./a.out | grep -a 'h' --line-buffered | grep 'h'

关于IO buffer 更多资料可以参考这篇文章: http://blog.gtwang.org/linux/linux-standard-streams-buffer/

quoras上的回答:https://www.quora.com/In-C-what-does-buffering-I-O-or-buffered-I-O-mean