题外话

C/C++中,为了读或写一个文件,我们需要首先需要调用open来打开相应的文件,完成对该文件的访问(read, write)后,再调用close将之关闭。那么为什么不再read和write内部完成打开和关闭文件的操作呢?这是因为打开一个文件时操作系统需要根据文件名,在文件系统中查找文件的位置、检验文件的属性(读、写、执行、追加等)进而验证本次操作是否有相应的权限,对于write调用,还需要为文件分配存储(磁盘)空间。所有这些操作都是非常费时的,于是操作系统打开文件时,就在内核中相应的文件打开表中添加该文件的文件指针(打开该文件的进程也会有自己的文件表),结束对文件的访问后,再从相应的文件表中删除文件指针表项。

关于缓冲区

相应地,缓冲区的存在,是为了减少对read和write的调用,每次调用都会将整块的数据写到缓冲区。C/C++中,有三种类型的缓冲区:

  • 全缓冲

在这种情况下,实际的I/O操作只有在缓冲区被填满了之后才会进行。对驻留在磁盘上的文件的操作一般是有标准I/O库提供全缓冲。缓冲区一般是在第一次对流进行I/O操作时,由标准I/O函数调用malloc函数分配得到的。缓冲区可以由标准I/O函数自动flush(例如缓冲区满的时候);或者我们对流调用fflush函数进行显式的刷新。

  • 行缓冲

在这种情况下,只有在输入/输出中遇到换行符的时候,才会执行实际的I/O操作。这允许我们一次写一个字符,但是只有在写完一行之后才做I/O操作。一般的,涉及到终端的流–例如标注输入(stdin)和标准输出(stdout)–是行缓冲的。

  • 无缓冲

标准I/O库不缓存字符。需要注意的是,标准库不缓存并不意味着操作系统或者设备驱动不缓存。

改变缓冲区大小位置以及缓冲类型有两个函数可供调用,setbuf和setvbuf,Google一下你就知道。

P.S.

看这个程序会输出什么:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
using namespace std;
 
int
main()
{
    printf("hello,world",getpid());
    fork();
    return 0;
}

这个又会输出什么?

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
using namespace std;
 
int
main()
{
    printf("hello,world\n",getpid());
    fork();
    return 0;
}

这是为什么呢?还是Google一下,看fork()做了些什么吧……^_^

Tags: ,.
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

Be the first to comment on this entry.

Name(required)
Mail (required),(will not be published)

RFC: Request For Comments. Orz..

Website(recommended)