关于系统级I/O的一些解析

输入/输出(I/O)是在主存和外部设备(如磁盘驱动器、终端、网络)之间复制数据的过程:
①输入操作是从I/O设备复制数据到主存。
②输出操作是从主存复制数据到I/O设备。
所有语言的运行时系统都提供执行I/O的较高级别工具。在Linux系统中,是通过使用由内核提供的系统级Unix I/O函数来实现这些较高级别的I/O函数的。

所有的I/O设备都被模型化为文件,而所有的输入和输出都被当作对相应文件的读和写来执行,所以说Linux中一切皆文件。
所有的输入和输出都以一种统一且一致的方式来执行:
①打开文件。应用程序要求内核打开相应文件,内核返回一个小的非负整数,叫 描述符。它在后续对此文件的所有操作中标识这个文件。
②Linux shell创建的每个进程开始时都有三个打开的文件。1.标准输入(描述符为0)。2.标准输出(描述符为1)。3.标准错误(描述符为2)。头文件<unistd.h>定义了常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO来代替显式的描述符值。
③改变当前的文件位置。每个打开的文件,内核保持着一个文件位置k,初始值为0。这个文件位置是从文件开头起始的字节偏移量。
④读写文件。1.读操作从文件复制n个字节到内存,从当前文件位置k开始将k增加到k+n。2.写操作是从内存复制n个字节到另一个文件,从当前位置k开始,更新k。
⑤关闭文件。

Linux内核将所有文件都组织成一个目录层次结构,由名为 ‘/’ 的根目录确定。
文件操作首先要的就是打开文件。使用open函数即可。函数原型为:
int open(char *filename,int flages,mode_t mode);
open函数将filename转换为一个文件描述符,并返回描述符数字。返回的描述符总是在进程中!!当前没有被打开!!的最小描述符。所以像:
fd1=open(“foo.txt”,O_RDONLY,0);的话,系统自动打开0,1,2这三个文件,所以当前没被打开的最小描述符是3,所以fd1=3。

✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂
I/O重定向
Linux shell提供了I/O重定向操作符,允许用户将磁盘文件和标准输入输出联系起来。我们可以利用dup2函数来让I/O重定向工作。dup2的函数原形为:
int dup2(int oldfd,int newfd);
dup2函数复制描述符表表项oldfd到描述符表表项newfd, 覆盖 描述符表表项newfd以前的内容。若newfd已经打开了,dup2会在复制oldfd之前关闭newfd。从此以后,任何写道标准输出的数据都被重定向到文件B。(这里用到了共享文件的知识)

dup2前:
关于系统级I/O的一些解析
dup2后:
关于系统级I/O的一些解析

✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂
我们可以看看这个函数的运行:

关于系统级I/O的一些解析
这个函数放在名为ffiles3.c的文件中,想要运行它首先先链接一下,csapp.h和csapp.c是自定义的头文件。最后的-o cpsatin将a.out命名为cpsatin。
./cpsatin a.txt将运行结果放到文件中(若是无a.txt文件,会自动先创建)。

关于系统级I/O的一些解析
关于系统级I/O的一些解析
a.text文件里的内容变化情况为:
pqrs---->write函数在文件末尾追加jklmn,此时文件内容为pqrsjklmn–>将fd1重定位给fd2,读写位置是指向fd2的文件末尾,此时写会覆盖jklmn,文件内容为pqrswxyzn–>继续追加,文件内容为:pqrswxyznef。