信息安全系统设计基础第九周学习总结—20135227黄晓妍

第十章系统级I/O

输入/输出(I/O)是主存和外部设备(I/O设备)(如磁盘驱动器、终端、网络)之间拷贝数据的过程。输入是从I/O设备拷贝到主存。反之则反。

学习Unix I/O的原因:

帮助理解其他的系统概念。

有时只能使用Unix I/O。例如:读取文件元数据(文件大小和创建时间)。另外,使用标准I/O库进行网编程非常冒险。

         10.1Unix I/O

Unix文件就是一个m字节的序列:b0,b1,b2….bm-1。所有的I/O设备都被虚拟化为文件。所有的输入输出都是在当成相对应的文件的读写。将设备映射为文件,Unix内核引出一个应用接口,Unix I/O。

输入输出的执行方式:

打开文件:

打开文件,内核会返回描述符。标准输入(STDIN_FILENO)描述符为0、标准输出(STDOUT_FILENO)描述符为1、标准错误(STDERR_FILENO)描述符为2。

改变当前文件位置:

         文件位置k,是文件开头起始的字节偏移量。

读写文件:

读是从文件拷贝到存储器。写相反。当k超过文件字节数m时,会触发end-of-file(EOF)条件。

关闭文件:

释放文件打开时创建的数据结构(释放文件的存储器资源),将描述符恢复到可用的描述符池中。

         10.2打开和关闭文件

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第1张图片

                   open函数的返回值是描述符。

                   filename文件路径字符串。

                   flag参数指明进程打算怎么访问这个文件。flag参数的值:

        

        

                   mode参数指定了新文件的访问权限位。mode参数的值:

      信息安全系统设计基础第九周学习总结—20135227黄晓妍_第2张图片

         10.3读和写文件

                   read 执行输入(读)

                   write执行输出(写)

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第3张图片

                   read 函数:从fd的当前文件位置 拷贝 最多n个字节到存储器位置 buf。

                                     返回值-1表示错误,0表示EOF,否则表示实际传送的字节数。

                   write 同理。

                   不足值:read和write传送的字节数少于应用程序的要求。

                                     读时遇到了EOF

                                     从终端读文本行:如果打开的文件是与终端相联的,那么每个read函数                                                                              将一次传送一个文本行,不足值=文本行大小。

                                     读和写网络套接字

         10.4RIO包健壮地读写

                   RIO包能自动地处理不足值。提供了:无缓冲的输入输出函数,带缓冲的输入函数。

                   10.4.1RIO的无缓冲的输入输出函数

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第4张图片

rio_readn函数从fd拷贝最多n字节到usrbuf。rio_writen也一样。rio_readn遇到EOF时只返回一个不足值,rio_writen绝不会返回不足值。对同一描述符,无缓冲的两个函数可以交叉调用

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第5张图片

当errno==EINTR时,表示函数被一个应用信号处理程序的返回中断了,则本次读的字节为0,重新使用read函数接着读入。

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第6张图片

                   10.4.2RIO的带缓冲的输入函数        

文本行就是一个由换行符结尾的ASCII码字符序列。换行符数字值为0x0a.rio_readlineb函数从内部读缓冲区拷贝一个文本行,当缓冲区为空时,会自动地调用read重新填满缓冲区。rio_readn带缓冲区的版本:rio_readnb。

信息安全系统设计基础第九周学习总结—20135227黄晓妍_第7张图片

                            rio_readinitb函数将fd和rp处的一个类型为rio_t的读缓冲区联系起来。

rio_readlineb从rp读出一个文本行(包括换行符)并把它存到usrbuf,并用空字符结束这个文本行。最多读maxlen-1个字节,剩下一个给结尾处的空字符。

                            rio_readnb最多读n个字节。

                            对同一描述符,带缓冲的函数之间可以交叉调用。

                 信息安全系统设计基础第九周学习总结—20135227黄晓妍_第8张图片

                            示例为RIO函数一次一行地从标准输入拷贝一个文本文件到标准输出。

                            信息安全系统设计基础第九周学习总结—20135227黄晓妍_第9张图片

                            rio_t读的缓冲区结构体。以及初始化它的代码。

                            信息安全系统设计基础第九周学习总结—20135227黄晓妍_第10张图片

rp->rio_cnt为缓冲区未读的字节。出错返回-1,EOF返回0,正常就接着读,直到>0。为0表示缓冲区为空,一旦为空就调用read将其填满。在缓冲区非空时,将n和rp->rio_cnt中的最小值拷贝到usrbuf,并且返回这个最小值。

                            信息安全系统设计基础第九周学习总结—20135227黄晓妍_第11张图片

rio_readlineb函数与rio_read相似,不同之处在于,每次调用都从读缓冲区返回一个字节,然后检查这个字节是否是换行符。

                            信息安全系统设计基础第九周学习总结—20135227黄晓妍_第12张图片

                            与rio_readn相似。

         10.5读取文件元数据

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第13张图片

         检索文件元数据的方式:调用stat和fstat函数。两者功能相似。

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第14张图片

         stat数据结构中的成员。重点掌握st_mode,st_size.

         st_size:文件字节数大小

         st_mode:文件访问许可位和文件类型。(普通文件:二进制文件和文本文件。目录文件:其他文件信息。套接字:通过网络与其他进程通信的文件。)

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第15张图片

    信息安全系统设计基础第九周学习总结—20135227黄晓妍_第16张图片

         判断了是三种文件的哪一种。(注意套接字是用“other”表示的)只判断了文件拥有者是否可读。

         10.6共享文件

         用三个相关的数据结构表示打开的文件:

                   描述符表:每个打开的描述符表项指向文件表中的一个表项。

                   文件表:打开的文件的集合是由一张文件表表示的,所有的进程共享这张表。包括文件位置、引用计数(当前指向该表项的描述符表项数),指向v-node表的指针。

                   v-node表:包含stat结构中大多数信息。

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第17张图片

         打开文件的内核数据结构

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第18张图片

         文件共享。共享了同一个磁盘文件

        信息安全系统设计基础第九周学习总结—20135227黄晓妍_第19张图片

         子父进程共享文件。子进程有一个父进程描述表符副本,所以他们共享打开文件的集合。注意,在内核删除相应文件表表项之前,子父进程必须都关闭他们的描述符。

         10.7 I/O重定向

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第20张图片

拷贝oldfd到newfd,将newfd的内容覆盖掉。如果newfd已经打开了,dup2会在覆盖前将它关闭。

         信息安全系统设计基础第九周学习总结—20135227黄晓妍_第21张图片

使用dup2函数将描述符1重定向到描述符4。

         10.8 标准I/O

         标准I/O库:一组高级输入输出函数。将一个打开的文件模型化为一个流,一个流即一个指向FILE类型的结构的指针。每个ANSI C程序开始时都有三个打开的流:stdin(标准输入),stdout(标准输出),stderr(标准错误)。

         类型为FILE的流是对文件描述符和流缓冲区的抽象。为了减小系统开销。

         10.9 综合:该使用哪些I/O函数

         大多数时候使用标准I/O就可以了。

         在网络套接字的时候使用RIO函数。需要格式化输出,使用sprintf函数格式化一个字符串,然后用rio_writen把它发送到套接口。格式化输入,使用rio_readlineb读一个完整的文本行,再使用scanf从文本行提取不同字段。

 

 

小结:

  本章内容相对较少,但是花费的时间一点都没有减少,在阅读代码上花费了较多时间。明显可以从阅读中看出本章与其他章的关联较大,有许多伏笔。本章主要是帮助我们理解系统级的输入输出,Unix I/O,告诉我们虽然我们有一些高级的标准库函数可以使用,但是在一些情况下,比如查看元数据,比如网络套接字时,必须使用系统级I/O。重点在于如何使用RIO包解决不停返回不足值这个问题。

 疑问:

  在书上p603上rio_read函数中,erro!=EINTR旁边的注释写的是被应用信号处理程序的返回中断,但是p601的rio_readn函数中,erro==EINTR才是被中断,我想了一下,满足这个条件return -1,说明这里是出错,应该是书上p603的注释有误。

 

参考资料: 《深入理解计算机系统》

你可能感兴趣的:(信息安全系统设计基础第九周学习总结—20135227黄晓妍)