fopen(3)
调用open(2)打开指定的文件(从系统调用开始),返回一个文件描述符(就是一个int类型的编号),分配一个FILE结构体(FILE *),其中包含该文件的描述符、I/O缓冲区(一个指针记录buffer位置)和当前读写位置等信息,返回这个FILE结构体的地址。
C标准I/O库函数(fopen,fclose,fputc,fgetc,fprintf,fscanf…)的运行空间是用户空间。
fgetc(3)
通过传入的FILE *参数找到该文件的描述符、I/O缓冲区和当前读写位置,判断能否冲I/O缓冲区中读到下一个字符,如果能读到就直接返回该字符,否则调用read(2),把文件描述符传进去,让内核读取该文件的数据到I/O缓冲区,然后返回下一个字符。
fputc(3)
判断该文件的I/O缓冲区是否有空间再存放一个字符,如果有空间则直接保存在I/O缓冲区中并返回,如果I/O缓冲区已满就调用write(2),让内核把I/O缓冲区的内容写回文件。
fclose(3)
如果I/O缓冲区中还有数据没写回文件,就调用write(2)写回文件,然后调用close(2)关闭文件,释放FILE结构体和I/O缓冲区。
C标准库的缓冲区分类
缓冲区的本质是一片存储区域。
全缓冲:缓冲区被填满时,才真正的触发系统调用。行缓冲:当出现换行时,立刻调用系统调用,把数据交给内核操作,标准输入输出都是行缓冲。无缓冲:缓冲区接收一个数据接进行一次系统调用。
行缓冲
#includeint main() { fputc('Y', stdout); //stdout 为标准输出 为行缓冲 //fputc('Y', stderr); //stdout 为无缓冲 //fputc('n', stdout); //遇到换行时输出Y while(1) { ; } return 0; }
没有遇到换行时没有任何输出。
遇到换行时输出Y
open
open函数可以打开或创建一个文件。
#include#include #include int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno。
pathname参数时要打开或创建的文件名,既可以是相对路径也可以是绝对路径。
flags参数有一系列常熟指可供选择,可以同时选择多个常数用按位或运算符连接起来,所以这些常数的宏定义都以0_开头,表示or。
必选项:以下三个常数中必须指定一个,且仅允许指定一个。
O_RDonLY 只读打开
O_WRonLY 只写打开
O_RDWR 可写可读打开
可选项:可以同时指定0个或多个,和必选项按位或起来作为flags参数。
O_CREAT 若此文件不存在则创建它。必需要提供第三个参数mode,表示文件的访问权限。
O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则返回出错。
O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断为0字节。
O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾。
O_NonBLOCK 对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O。
第三个参数mode指定文件权限,可以用八进制数表示,比如0644表示-rw-r–r--,也可以用S_IRUSR、S_IWUSR等宏定义按位或起来表示。
#include关闭文件#include #include #include #include int main(int argc, char *argv[]) { if(argc < 2) { //判断传入的参数个数,小于2打印错误信息 printf("cmd errorn"); return -1; } int fd = open(argv[1], O_WRonLY | O_CREAT, 0644); //打开一个文件,没有就创建,并指定文件的权限 if(fd < 0) { //判断返回的文件描述符是否出错 perror("OPEN"); return -1; } else { perror("OPEN"); } return 0; }
close
close函数关闭一个已打开的文件
#includeint close(int fd);
返回值:成功返回0;出错返回-1并设置errno
参数fd是要关闭的文件描述符。当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止内核也回自动关闭它打开的所有文件。
由open返回的文件描述符一定是该进程尚未使用的最小描述符。
#include#include #include #include #include #include int main(int argc, char *argv[]) { if(argc < 2) { //判断传入的参数个数,小于2打印错误信息 printf("cmd errorn"); return -1; } int fd = open(argv[1], O_WRonLY | O_CREAT, 0644); //打开一个文件,没有就创建,并指定文件的权限 if(fd < 0) { //判断返回的文件描述符是否出错 perror("OPEN"); return -1; } else { perror("OPEN"); } close(fd); return 0; }



