视频地址:
http://player.bilibili.com/player.html?aid=31289365&bvid=BV1iW411d7hd&cid=85207140&page=16
课件地址:
对应于书中的第10章。
Linux将所有资源都看成文件的形式。
到这就进入了新的一部分,过去一直假设程序时独立运行的,但是其实应用程序可利用操作系统提供的服务来与I/O设备及其他程序通信,这一部分将学习Unix操作系统提供的基本I/O服务,以及如何利用这些服务来构造引用程序。
**输入/输出(I/O)**是在主存和外部设备(磁盘驱动器、终端和网络)之间复制数据的过程。输入操作就是从I/O设备复制数据到主存,输出操作就是将主存数据复制到I/O设备。这里我们将所有I/O设备都抽象为Linux文件,即m个字节的序列,这样所有输入和输出操作都可以看成是对文件的读写,使得所有输入和输出都能以统一的方法来执行:
打开文件:一个应用程序通过要求内核打开某个文件,来确定要访问的I/O设备。此时内核会记录有关该文件的所有信息,而应用程序会获得该文件的描述符,来标识该文件。
修改当前读写文件的位置:对于每个打开的文件,内核会维护一个文件位置k来表示当前要读写文件的位置,是从文件头开始的字节偏移量,初始化为0。应用程序可以通过seek
操作来修改读写文件的位置。
<aside> 💡 但是无法修改基于终端的输入的文件位置,因为无法移动、备份和恢复先前已读入的数据,也无法提前接收还未键入的数据。比如套接字。
</aside>
**读写文件:**读文件就是在文件中从k开始复制n个字节到内存,并更新k=k+n
,如果k超出了文件大小,则会给引用程序返回EOF。而写文件就是从内存 复制n个字节到文件位置k处,然后更新k=k+n
。
**关闭文件:**当应用程序通知内核关闭文件时,内核会释放打开文件的数据结构,并将该描述符恢复到可用的描述符池中。
通过将I/O设备抽象为文件的形式,使得对I/O设备的输入输出统一为对文件的读写操作,而应用程序可以通过文件描述符来对指定的I/O设备进行操作。在创建进程时,内核会默认打开三个文件,标准输入(描述符为0)、标准输出(描述符为1)和标准错误(描述符为2),可通过STDIN_FILENO
、STDOUT_FILENO
和STDERR_FILENO
代替描述符来访问这三个文件。当进程终止时,内核会关闭所有打开的文件,并释放内存资源。
在Linux中,文件具有不同的类型:
**文本文件(Text File):**只含有ASCII或Unicode字符的普通文件,是一系列文本行的序列,以\\n
符号间隔。
**二进制文件(Binary File):**所有其他的文件。
应用程序会进行区分,而对于内核而言没有区别。