I/O概念

就C程序而言,所有的I/O操作只是简单地从程序移进或移出字节的事情。因此,毫不惊奇的是,这种字节流便被称为流(stream)。程序只需要关心创建正确的输出字节数据,以及正确地解释从输入读取的字节数据。特定I/O设备的细节对程序员是隐藏的。

简单地说,流是对信息的一种抽象。C系统在处理文件(文本文件和二进制文件)时,并不区分类型,都看成是字符流,按字节进行处理。

当一个程序启动时,标准输入、输出、出错三个流就已经被自动打开,并对应到默认的物理终端。这三个标准I/O流通过预定义(stdio.h)文件指针stdin,stdout,stderr加以引用当一个进程正常终止时(直接调用exit(),或从main返回)所有打开的标准I/O流都会被关闭,所有带未写缓冲数据的I/O流都会被冲洗。

注意: 

在main()中return(expr)等价于exit(expr),而exit则调用fclose()关闭每个文件描述符并刷洗对应缓存。 

在Linux的应用程序中,通常用文件描述符0,1,2与标准输入,标准输出,标准出错输出相关联。为符合POSIX规范,在中,0,1,2分别被替换成常量符号STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。

缓冲区

缓冲文件系统是为了减少系统调用(system call)read write的调用频率,降低操作系统负担。

缓冲文件系统,系统自动在内存中为每一个正在使用的文件开辟一个缓冲区,从内存向磁盘输出数据或从磁盘读取数据是,都是先放到缓冲区。 

下图以fgets/fputs示意了I/O缓冲区的作用,使用fgets/fputs函数时在用户程序中也需要分配缓冲区(图中的buf1buf2),注意区分用户程序的缓冲区和C标准库的I/O缓冲区。

标准I/O提供了三种类型的缓存:
全缓存。在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。对于驻在磁盘上的文件通常是由标准I/O库实施全缓存的。

行缓存。在这种情况下,当在输入和输出中遇到新行符时,标准I/O库执行I/O操作。这允许我们一次输出一个字符(用标准I/O fputc函数),但只有在写了一行之后才进行实际I/O操作。

不带缓存。标准I/O库不对字符进行缓存。如果用标准I/O函数写若干字符到不带缓存的流中,则相当于用write系统调用函数将这些字符写至相关联的打开文件上。

ANSI C要求下列缓存特征:

(1) 当且仅当标准输入和标准输出并不涉及交互作用设备时,它们才是全缓存的。
(2) 标准出错决不会是全缓存的。 

二进制流和文本流

流有最小的信息单元就是二进制位,含有最小的信息包就是字节,C标准库提供两种类型的流:二进制流(binary stream)和文本流(text stream)。

二进制流是有未经处理的字节构成的序列;

文本流的有些特性在不同的系统中可能不同。其中之一就是文本行的最大长度,标准规定至少允许254个字符。另一个可能不同的特性就是文本行的结束方式,在MS-DOS中,文本文件约定以一个回车符和一个换行符结尾,但是在UNIX系统中只使用一个换行符结尾。

文件

FILE是一种数据结构,定义在stdio.h文件中,用于访问一个流,如果同时激活了几个流,每个流都会有一个FILE与之关联。

对于C程序,运行时系统必须提供至少三个流:标准输入,标准输出,标准错误,分别用stdin,staout和stderr来表示,它们都是一个指向FILE结构的指针,标准输入是缺省情况下的输入来源,标准输出是缺省的输出设置。标准错误是写入错误信息的地方,perror函数把它的输出也写到这个地方。

标准I/O常量

stdio.h中还定义了众多的输入和输出关联的常量,如:

EOF:表示文件末尾。

FILENAME_MAX:表示一个字符数组应该多大以便容纳编译器所支持的额最长合法文件名。

posted @ 2018-04-05 16:53  刘-皇叔  阅读(498)  评论(0编辑  收藏  举报