一、标准IO概念
标准IO在系统调用的上一层多加了一个缓冲区,也因此引入了流的概念,在UNIX/Linux下表示为FILE*(并不限于UNIX/Linux,ANSI C都有FILE的概念),FILE实际上包含了为管理流所需要的所有信息:实际I/O的文件描述符,指向流缓存的指针(标准I/O缓存,由malloc分配,又称为用户态进程空间的缓存,区别于内核所设的缓存),缓存长度,当前在缓存中的字节数,出错标志等。标准I/O对每个I/O流自动进行缓存管理,它提供了三种类型的缓存:
-
全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。
-
行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。
-
无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。
二、行缓存的验证案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("hello world!");
while(1)
{
sleep(1);
}
return 0;
}
以上程序编译后,并不能输出任何信息。原因是使用printf输出hello world后,没有换行符。printf的缓冲是属于行缓冲的,输出遇到新行符或缓冲满时,才执行标准的I/O操作。此程序由于执行到了while中的循环,一直在循环。缓冲没有满,也没遇到换行符。所以屏幕无任何输出。
当去掉while循环,程序输出后立马结束,缓存中的信息就会输出出来。
三、FILE结构体
包含于#include <stdio.h>里,以下仅是FILE结构体部分参数,具体可查看头文件。
fd 文件描述符就是联系的标准IO和系统调用IO的。
标准C的IO 都是带缓存的。调用标准C,写入或读取数据时候,先读写到缓存中,然后才输入或输出到定义的变量 buf 或 文件中。
缓存的操作如下:
缓存遇到换行符或是return 或者写满缓存后的时候,才会输出。
数据先写进缓存,然后再输出到文件或屏幕上。
stdin:标准输入,scanf 类函数就是默认的使用此函数
stdout:标准输出,printf 函数默认使用此
stderr:标注错误
这三个就是FILE 类型结构体指针,也称为流指针
四、函数格式定义
1. fopen()函数 – 用于打开一个文件,返回一个指向该文件的文件指针
#include<stdio.h>
FILE* fopen(const char *filename