互联网站备案表,推广型网站建设电话,网站建设合同书样本,邯郸市市长文章目录 前言基础IO定义系统IO接口文件描述符重定向原理缓冲区刷新 前言
要知道每个函数/接口的全部参数和返回值建议去官网或者直接在Linux的man手册中查#xff0c;这不是复制粘贴函数用法的文章。 C语言文件读写介绍链接
基础IO定义
IO是Input/Output的缩写#xff0c… 文章目录 前言基础IO定义系统IO接口文件描述符重定向原理缓冲区刷新 前言
要知道每个函数/接口的全部参数和返回值建议去官网或者直接在Linux的man手册中查这不是复制粘贴函数用法的文章。 C语言文件读写介绍链接
基础IO定义
IO是Input/Output的缩写它是计算机领域中常用的术语用来描述计算机系统与外部设备之间的数据交换过程。输入Input是指将外部数据或指令传输到计算机系统中而输出Output则是指将计算机系统处理后的数据或结果传输到外部设备中。例如键盘、鼠标、显示器、打印机等都属于外部设备它们与计算机之间的数据交换过程就是通过输入和输出来实现的。
系统IO接口
在说系统IO接口之前需要区分语言库IO函数和系统IO接口的区别库函数IO接口如C语言中的fopen函数 fseek函数 ftell函数 rewind函数 等。这些都是语言库对系统IO接口open write read close 等IO接口的再封装。 如图open write read close 等IO接口在用户操作接口层fopen函数 fseek函数 ftell函数 rewind函数 等在用户层。
文件描述符
文件描述简写为fd
在Linux中每个进程都有一个task_struct, task_struct 里有 *files指针 *files指针指向 files_struct结构体(files_struct结构体内含有file_struct结构体的列表的指针) , fd 是 files_struct 内那个指向的数组 的下标文件描述符本质是文件信息结构体数组下标。(注意files_struct 和 file_struct 差一个字母 ) 在调用系统IO接口open打开文件后会返回打开文件描述符。文件描述符是一个非负的整数。在Linux操作系统中的进程中默认会打开三个文件描述符分别是0 , 1 , 2 对应三个文件标准输入文件 标准输出文件 标准错误文件 。(Linux中一切皆文件硬件如显示器键盘鼠标接入后都是Linux系统中的一个个文件)
文件描述符的分配原则是当一个进程打开新的文件该文件的信息存放在文件信息存储数组中未被使用的且素组下标最小的位置。(也就是说如果默认被标准输入文件使用的0下标在新文件被打开之前就关闭新文件打开后就会占据0下标来记录新打开文件的文件信息)
重定向原理
重定向原理关闭文件信息数组newfd下标对应的文件并将newfd存储的文件设置为oldfd存储的文件信息。此时newfd 和 oldfd 文件描述符实际对应的都是重定向之前 newfd对应的文件信息即可通过newfd 和 oldfd 文件描述访问同一个文件。
将oldfd实际对应的文件信息给newfd 重定向使用
使用方法一利用函数
int dup2(int oldfd, int newfd);参数 1.oldfd一个整数值表示要复制的旧文件描述符。 2.newfd一个整数值表示新的文件描述符。 返回值 如果成功返回值为newfd 如果失败返回值为-1并设置errno来指示错误类型。 例
#include stdio.h
#include unistd.h
#include fcntl.hint main()
{// 打开一个文件用于写入int fd open(example.txt, O_WRONLY | O_CREAT, 0644); if (fd -1) {perror(open);return 1;}// 将标准输出重定向到文件描述符fd所指向的文件int newfd dup2(fd, STDOUT_FILENO); if (newfd -1) {perror(dup2);return 1;}printf(This will be written to example.txt\n); // 这行内容将会写入到example.txt文件中close(fd); // 关闭文件描述符fdclose(newfd); // 关闭新的文件描述符newfdreturn 0;
}使用方法二在命令行利用重定向符号
在Linux中重定向符号用于将命令的输出结果重定向到指定的文件中。它的作用是将命令的标准输出stdout输出到文件中而不是显示在终端上。 重定向符号的使用方法是在命令后面加上符号紧跟着要输出到的目标文件名。例如
command filenamecommand表示要执行的命令filename表示要将输出结果写入的目标文件名。 当执行带有重定向符号的命令时如果目标文件已经存在则会被覆盖如果目标文件不存在则会创建一个新文件。重定向符号会将命令的标准输出重定向到目标文件中不会在终端上显示输出结果。以下是几个示例演示如何使用重定向符号进行输出重定向
将ls命令的输出结果写入到名为file.txt的文件中
ls file.txt将command命令的错误输出标准错误流写入到名为error.txt的文件中
command 2 error.txt缓冲区刷新
什么是缓冲区
缓冲区区分
前面IO分为系统IO和语言库封装的IO函数语言库在封装IO接口的同时也对IO缓冲区刷新策略做了封装C语言的缓冲刷新策略和Linux本身缓冲区刷新策略大致一样。但C语言的函数在系统缓冲区的基础上在语言库层面(用户层)再设置了一个缓冲区该缓冲区具体在FILE结构体中。
Linux 缓冲区刷新策略: 全缓冲fully buffered默认情况下Linux使用全缓冲模式。在全缓冲模式下数据会在缓冲区中累积一定量后才会被写入磁盘这样可以减少磁盘I/O操作的次数提高性能。但是这也意味着数据可能会在缓冲区中停留一段时间直到缓冲区满或者手动刷新。 行缓冲line buffered对于某些特殊的文件如终端设备Linux会使用行缓冲模式。在行缓冲模式下数据会在遇到换行符时立即写入磁盘这样可以保证及时显示输出结果。但是对于普通文件行缓冲模式并不常见。 无缓冲unbuffered在某些情况下我们可能需要禁用缓冲区直接将数据写入磁盘。这种模式下数据会立即写入磁盘但是由于没有缓冲区会导致频繁的磁盘I/O操作性能较差。
库函数刷新策略证明
#include stdio.h
#include string.h
int main()
{const char *msg0hello printf\n;const char *msg1hello fwrite\n;const char *msg2hello write\n;printf(%s, msg0);fwrite(msg1, strlen(msg0), 1, stdout);write(1, msg2, strlen(msg2));fork();return 0;
}直接运行结果
hello printf
hello fwrite
hello write./test file 重定向之后结果:hello write
hello printf
hello fwrite
hello printf
hello fwrite现象解释C语言库函数缓冲区在输入对象为终端时刷新策略为行缓冲直接运行时在遇到换行符时就将库函数缓冲区的内容刷新到系统缓冲区再由系统缓冲区输入到终端上。重定向后输入目标为普通文件刷新策略变为全缓冲write输入到系统缓冲区fwrite 和 printf 属于C语言库函数输入了C语言库函数缓冲区在子进程创建后会拷贝一份C语言库函数缓冲区 (因为拷贝了FILE结构体C语言库函数缓冲区即为FILE结构体的成员) 到子进程。 进程结束时会将父子进程C语言库函数的缓冲区的内容输入系统缓冲区再由系统缓冲区一起刷新到终端(屏幕)。