[转] 关于流和缓冲


标准I/O提供了三种类型的缓存:
(1) 全缓存。在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。对于驻在磁盘上的文件通常是由标准I/O库实施全缓存的。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc(见7 . 8节)获得需使用的缓存。
术语刷新(flush)说明标准I/O缓存的写操作。缓存可由标准I/O例程自动地刷新(例如当填满一个缓存时),或者可以调用函数fflush刷新一个流。值得引起注意的是在UNIX环境中,刷新有两种意思。在标准I/O库方面,刷新意味着将缓存中的内容写到磁盘上(该缓存可以只是局部填写的)。在终端驱动程序方面(例如在第11章中所述的tcflush函数),刷新表示丢弃已存在缓存中的数据。
(2) 行缓存。在这种情况下,当在输入和输出中遇到新行符时,标准I/O库执行I/O操作。这允许我们一次输出一个字符(用标准 I/O fputc函数),但只有在写了一行之后才进行实际I/O操作。当流涉及一个终端时(例如标准输入和标准输出),典型地使用行缓存。对于行缓存有两个限制。第一个是:因为标准I/O库用来收集每一行的缓存的长度是固定的,所以只要填满了缓存,那么即使还没有写一个新行符,也进行I/O 操作。第二个是:任何时候只要通过标准输入输出库要求从(a)一个不带缓存的流,或者(b)一个行缓存的流(它预先要求从内核得到数据)得到输入数据,那么就会造成刷新所有行缓存输出流。在(b)中带了一个在括号中的说明的理由是,所需的数据可能已在该缓存中,它并不要求内核在需要该数据时才进行该操作。很明显,从不带缓存的一个流中进行输入((a)项)要求当时从内核得到数据。
(3) 不带缓存。标准I/O库不对字符进行缓存。如果用标准I/O函数写若干字符到不带缓存的流中,则相当于用write系统调用函数将这些字符写至相关联的打开文件上。标准出错流stderr通常是不带缓存的,这就使得出错信息可以尽快显示出来,而不管它们是否含有一个新行字符。
ANSIC要求下列缓存特征:
(1) 当且仅当标准输入和标准输出并不涉及交互作用设备时,它们才是全缓存的。
(2) 标准出错决不会是全缓存的。
但是,这并没有告诉我们如果标准输入和输出涉及交互作用设备时,它们是不带缓存的还是行缓存的,以及标准输出是不带缓存的,还是行缓存的。SVR 4和4.3+ BSD的系统默认使用下列类型的缓存:
    标准出错是不带缓存的。
    如若是涉及终端设备的其他流,则它们是行缓存的;否则是全缓存的。

    我们经常要用到标准输入和输出,而ANSI C对stdin、stdout和stderr的缓存特征没有强行的规定,以至于不同的系统可能有不同的stdin、stdout和stderr的缓存特征。目前主要的缓存特征是:stdin和stdout是行缓存;而stderr是无缓存的。


参考:
1. 《UNIX环境高级编程》第五章, Stevens
2. 关于流和缓冲区的理解以及一般标准输入问题的解决方法小结(很详细)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值