介绍
- 不仅在 UNIX 系统,在很多操作系统上都实现了标准 I/O 库
- 标准 I/O 库由 ANSIC 标准说明
- 标准 I/O 库处理很多细节,如缓存分配、以优化长度执行 I/O 等,这样使用户不必关系如何选择合适的块长度
- 标准 I/O 在系统调用函数基础上构造的,它便于用户使用
- 标准 I/O 库及其头文件
stdio.h
为底层 I/O 系统调用提供了一个通用的接口
文件指针
- FILE 指针:每个被使用的文件都在内存中开辟一个区域,用来存放文件的有关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名为 FILE。(在
libio.h
中定义) - 标准 I/O 库的所有操作都是围绕流(stream)来进行的,在标准 I/O 中,流用
FILE*
来描述。 - 标准 I/O 是由 Dennis Ritchie 在 1975 年左右编写的。
流(stream)
定义:所有的 I/O 操作仅是简单的从程序移进或者移出,这种字节流,就称为流。
分类:
- 文本流
- 定义:在流中处理的数据是以字符出现。在文本流中,
\n
被转换成回车符 CR 和换行符 LF 的 ASCII 码 0DH 和 0AH。而当输出时,0DH 和 0AH被转换成\n
- 数字
2001
在文本流中的表示方法为 ‘2’ ‘0’ ‘0’ ‘1’;ASCII: 50 48 48 49
- 定义:在流中处理的数据是以字符出现。在文本流中,
- 二进制流
- 定义:流中处理的是二进制序列。若流中有字符,则用一个字节的二进制 ASCII 码表示;若是数字,则用对应的二进制数表示。对
\n
不进行变换 - 数字 2001 在二进制中的表示方法为 00000111 11010001
- 定义:流中处理的是二进制序列。若流中有字符,则用一个字节的二进制 ASCII 码表示;若是数字,则用对应的二进制数表示。对
文件缓冲
缓冲文件系统(高级磁盘IO)
- 目的:尽量减少使用 read/write 的调用(关键是减少堆栈的初始化次数)
- 定义:系统自动的在内存中为每一个正在使用的文件开辟一个缓冲区,从内存向磁盘输出数据必须先送到内存缓冲区,装满缓冲区在一起送到磁盘中去。从磁盘中读数据,则一次从磁盘文件将一批数据读入到内存缓冲区中,然后再从缓冲区逐个的将数据送到程序的数据区。
- 分类:全缓存,行缓存,不缓存。
- 库缓存在文件打开之后第一次进行 IO 操作时创建
- 在用户空间
malloc
的一段空间
非缓冲文件系统(低级磁盘 IO)
- 定义:依靠于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出。
标准 I/O 提供了三种类型的缓存
- 全缓存:
- 当填满 I/O 缓存后才进行实际 I/O 操作(或者执行
fflush
、exit
、return
、先写后读),系统通过调用malloc
来获得所需要的缓冲区域,默认值。 - 4K大小
- 当填满 I/O 缓存后才进行实际 I/O 操作(或者执行
- 行缓存:
- 当填满 I/O 缓存或者遇到新行符
\n
(或者执行fflush
、exit
、return
)才进行实际 I/O 操作 - 1K大小
- 用于标准输入输出、终端
- 当填满 I/O 缓存或者遇到新行符
- 无缓存
- 标准 I/O 库不对字符进行缓冲,例如
stderr
。 - 很多人机交互界面要求不可全缓存。
- 标准出错绝不会是全缓存的。
- 标准 I/O 库不对字符进行缓冲,例如
#include<stdio.h>
int main(int argc, const char *argv[]){
printf("aaaaa");
fflush(stdout);
// printf("\n");
// write(1,"aaaaa\n",6);
// scanf();
while(1);
return 0;}
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
int main(int argc, const char *argv[]){
FILE *fp = fopen("test.txt","w+");
if(NULL == fp){
//printf("fail to fopen : %s\n",strerror(errno));
perror("fail to fopen");
exit(1);}
printf("stdout:%d\n",stdout->_IO_buf_end - stdout->_IO_buf_base);
printf("stdout:%d\n",stdout->_IO_buf_end - stdout->_IO_buf_base);
printf("fp:%d\n",fp->_IO_buf_end - fp->_IO_buf_base);
fputc('a',fp);
printf("fp:%d\n"