缓冲输入输出

ericming200409 2011-03-07 10:28:20
基于流的操作最终都会调用read或write进行操作。即流的内部封装了这两个系统调用。

缓冲分如下三种:

全缓冲(相应宏_IO_FULL_BUF):直到缓冲区被填满,菜调用系统I/O函数。磁盘文件读写通常是全缓冲的。

行缓冲(相应宏_IO_LINE_BUF):直到遇到换行符'\n',才调用系统I/O函数。标准输入输出都是行缓冲的。

无缓冲(相应宏_IO_UNBUFFERED):没有缓冲,数据立即读入或输出到外存文件和设备上。例如标准出错。



对于写操作的缓冲都比较好理解,我现在对读操作的缓冲很迷糊,比如全缓冲,读的时候到底什么时候进行实际的读,是当待读的内容达到缓冲区大小吗?

再比如行缓冲,遇到换行符才进行实际读,如果实际上没读,又怎么知道有没有遇到换行符呢?
...全文
143 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ericming200409 2011-03-08
  • 打赏
  • 举报
回复
经过讨论,现在基本可以总结如下:
1 一般情况下, 全缓冲输入输出,都是以缓冲区大小为单位来进行实际读写操作的;
2 一般情况下,行缓冲都是以行为单位来进行实际I/O的。

但是,那是一般情况,有很多情况会导致缓冲区的冲洗,那么有哪些方式会导致冲洗缓冲区呢?
justkk 2011-03-08
  • 打赏
  • 举报
回复
还真没留意这个问题哈

个人理解:
1、对于行缓冲,输入时其实已经读入了,但是直到按回车之后,读函数(比如fgets)才返回给应用程序
2、对于普通文件,读时应该先读入一个完整的缓冲区的大小(即使应用程序只要求读一个字节),然后再返回给应用程序指定的字节
louyong0571 2011-03-08
  • 打赏
  • 举报
回复
说下我的认识,全缓冲读文件应该是一下子读满缓冲区,后面不需要每次去读文件,这个样子吧。
justkk 2011-03-08
  • 打赏
  • 举报
回复
嗯 读的时候内核要确保磁盘数据是一个稳定状态
ericming200409 2011-03-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 justkk 的回复:]

当从内核中读数据时,为什么要fflush()输出缓冲区?
不甚明白
[/Quote]

我的理解是,如果我们写了一行,但是还在缓冲区没有写到磁盘, 之后我们又读一行,如果不flush输出缓冲区的话,则读出来的很可能不是我们想读的那行,因为写会改变文件的布局,比如我们想读第1行,而写缓冲区刚好写的就是第一行。
justkk 2011-03-08
  • 打赏
  • 举报
回复
当从内核中读数据时,为什么要fflush()输出缓冲区?
不甚明白
justkk 2011-03-08
  • 打赏
  • 举报
回复
对于全缓冲的,书上没有提及
同时打开读写,应该是两个缓冲区,否则读入缓冲区的数据如果还没有返回给应用程序,在输出时会被输出
ericming200409 2011-03-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 justkk 的回复:]

1、缓冲区满了
2、你调用了fflush()
3、whenever input is requested through the standard I/O library from either (a) an unbuffered stream or (b) a line-buffered stream (that requires data to be requested from the……
[/Quote]

3是出自apue吧,它只是说当要从内核拿数据时,所有的行缓冲区会被flush, 如果是全缓冲的呢,我觉得也应该被flush啊。

另外,如果一个流同时打开来读写, 读写各一个缓冲区,还是公用一个缓冲区?
justkk 2011-03-08
  • 打赏
  • 举报
回复
1、缓冲区满了
2、你调用了fflush()
3、whenever input is requested through the standard I/O library from either (a) an unbuffered stream or (b) a line-buffered stream (that requires data to be requested from the kernel), all line-buffered output streams are flushed. The reason for the qualifier on (b) is that the requested data may already be in the buffer, which doesn't require data to be read from the kernel. Obviously, any input from an unbuffered stream, item (a), requires data to be obtained from the kernel.
ericming200409 2011-03-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bluejays 的回复:]

随便举个例子吧:
for (i=0; i<3; i++)
a[i] = getchar();
输入abc但是不按回车,那么程序就会停在i=0而不会继续,直到按了回车,才会给a[0]到a[3]全都赋值。
用gdb单步调试一下就看得很清楚
[/Quote]
如果是针对普通文件的读呢,

关于全缓冲,能不能也举个例子

bluejays 2011-03-07
  • 打赏
  • 举报
回复
scanf也类似
scanf("%d", &a);
scanf("%d", &b);
scanf("%d", &c);
输入1 2 3但是不按回车,程序就会停在第一行,只有按了回车才会继续
bluejays 2011-03-07
  • 打赏
  • 举报
回复
随便举个例子吧:
for (i=0; i<3; i++)
a[i] = getchar();
输入abc但是不按回车,那么程序就会停在i=0而不会继续,直到按了回车,才会给a[0]到a[3]全都赋值。
用gdb单步调试一下就看得很清楚

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧