20145308 《信息安全系统设计基础》第9周学习总结

20145308 《信息安全系统设计基础》第9周学习总结

教材学习内容总结

  • 输入/输出(I/O)是在主存和外部设备之间拷贝数据的过程

10.1 Unix I/O

  • Unix文件:m个字节的序列
  • 所有的I/O设备都被模型化为文件,所有的输入和输出都被当作对相应文件的读和写来执行
  • Unix内核引出一个简单、低级的应用接口,称为Unix I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行
    • 打开文件:宣告想要访问一个I/O设备,内核返回描述符(小的非负整数)
    • 改变当前的文件位置:内核保持着一个文件位置k,是从文件开头起始的字节偏移量
    • 读写文件:文件从当前文件位置K开始读写
    • 关闭文件:内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中

10.2 打开和关闭文件

  • 进程是通过调用open函数来打开一个已存在的文件或创建一个新文件的
    • open成功返回新文件描述符,出错为1
    • open函数:filename文件描述符,flags指明进程打算如何访问文件,mode指定了新文件的访问权限位
    • 文件的访问权限位被设置为mode&umask
    • close成功为0,出错返回-1

10.3 读和写文件

  • 应用程序分别通过调用read和write函数来执行输入和输出的
    • read成功返回读的字节数,若EOF为0,出错为-1
    • write成功则为写的字节数,出错则为-1
  • 不足值出现原因
    • 读时遇到EOF
    • 从终端读入文本行:打开文件是与终端相关联的,每个read函数将一次传送一个文本行,返回的不足值等于文本行的大小
    • 读和写网络套接字:打开的文件对于网络套接字,内部缓冲约束和较长的网络延迟会引起read和write返回不足值

10.4 用RIO包健壮地读写

  • RIO:I/O包,会自动为你处理不足值
  • RIO提供两种函数
    • 无缓冲的输入输出函数:直接在存储器和文件之间传送数据,没有应用级缓冲,对二进制数据读写到网络和从网络读写二进制数据
    • 带缓冲的输入函数:允许高效的从文件中读取文本行和二进制数据,这些文件的内容缓存在应用级缓冲区内,带缓冲的RIO输入函数是线程安全的,在同一个描述符上可以被交错的调用

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

  • 通过调用rio_readn和rio_writen函数,应用程序可以在存储器和文件之间直接传送数据
    • 成功则为传送的字节数,EOF则0(只对rio_readn),出错则为-1
    • rio_writen遇到EOF绝不会返回不足值
    • 对同一个描述符,可以交错调用rio_readen和rio_writen

10.4.2 RIO的带缓冲的输入函数

  • 文本行:一个由换行符结尾的ASCII码字符序列
  • 换行符('\n')与ASCII码中(LF)相同,数字值为0x0a
  • 包装函数rio_readlined,从一个内部读缓冲区拷贝一个文本行,当缓冲区变空时,自动调用read重新填充缓冲区
  • rio_readnb,对于即包含文本行也包含二进制数据的文件,rio_readn带缓冲区的版本
  • RIO读程序的核心是rio_read函数,Unix read函数的带缓冲版本

10.5 读取文件元数据

  • 应用程序能够通过调用stat和fstat函数,检索到关于文件的信息(文件的元数据),成功为0,出错为-1
    • st_size包含了文件的字节数大小,st_mode成员编码了文件访问许可位和文件类型
  • 普通文件:包括某种类型二进制或文本数据
  • 目标文件:包含关于其他文件信息
  • 套接字:一种用来通过网络与其他进程通信的文件
  • 使用宏和stat函数来读取和解释一个文件的st_mode位

10.6 共享文件

  • 内核用三个相关的数据结构表示打开的文件:描述符表、文件表、v-node表
  • 描述符表:每个进程都有独立的描述符表,表项是由进程打开的文件文件描述符来索引的,每个描述符表项都指向文件表中的一个表项
  • 文件表:打开的文件的集合,所有进程共享一个表,表项组成包括当前的文件位置、引用计数和指向v-node表对应表项的指针
  • v-node表:所有进程共享,表项包括stat结构中的大多数信息

10.7 I/O重定向

  • Unix外壳提供I/O重定向操作符,允许用户将磁盘文件和标准输入输出联系起来
    • 利用int dup2(int oldfd,int newfd),成功返回非负描述符,出错为-1
    • dup2函数拷贝描述表表项oldfd到描述表表项newfd,覆盖newfd以前的内容,如果newfd已经打开了,dup2会在拷贝oldfd前关闭newfd

10.8 标准I/O

  • 标准I/O库,一组高级的输入输出函数,将一个打开的文件模型化为一个流(指向FILE类型的结构的指针)
  • ANSI C程序开始时有三个打开的流:标准输入stdin、标准输出stdout和标准错误stderr
  • 类型为FILE的流是对文件描述符和流缓冲区的抽象

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

  • 标准I/O函数是磁盘和终端设备I/O之选
  • 标准I/O流限制
    • 跟在输出函数之后的输入函数:在每个输入操作前刷新缓冲区
    • 跟在输入函数之后的输出函数:对同一个代开的套接字打开两个流,一个用来读,一个用来写
  • 在网络套接字上不使用标准I/O函数来进行输入和输出,使用健壮的RIO函数

附录A 错误处理

  • 给定某个系统程序的包装函数,包装函数调用基本函数并检查错误

A.1 Unix系统中的错误处理

  • Unix风格的错误处理
    • Unix早期开发出来的函数返回值既包括错误代码又有有用结果,例如fork和wait
    • 遇到错误返回-1,并将全局变量errno设置为指明错误原因的错误代码
  • Posix风格的错误处理
    • 只用返回值来表明成功(0)或失败(非0),任何有用的结果都返回在通过引用传递进来的函数参数中
  • DNS风格的错误处理
    • gethostbyname和gethostbyaddr函数检索DNS主机条目,在失败时返回NULL指针,并设置全局变量h_errno
  • 错误报告函数小结

A.2错误处理包装函数

  • Unix风格的错误处理包装函数
  • Posix风格的错误处理包装函数
  • DNS风格的错误处理包装函数

教材学习中的问题和解决过程

  • 习题5.1,答案不是'
  • 看了题目后,以为是分别两次读文件,就直接认为答案是'f'了,但是看了讲解,发现自己忽略了重定向后,两个文件描述符都指向一个文件,文件的引用计数也要加一,答案是'o'

本周代码托管截图


托管链接:http://git.oschina.net/yg1022/CSAPP2E

其他(感悟、思考等,可选)

  • 本周学习了I/O,其中包含Unix系统提供的少量的系统级函数,利用RIO包读写,和利用基于Unix I/O的标准I/O库进行读写。还学习了附录A中的内容,主要学习了Unix系统中的错误处理以及用包装函数来处理错误。学习了两部分内容,相同点是无论是I/O还是错误,都会用包装函数来处理错误。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 1/2 25/30 学习Linux指令
第二周 50/50 1/3 25/55 Linux系统下的开发环境
第三周 20/70 1/4 25/80 信息的表示和处理
第五周 20/90 1/5 30/110 程序的机器级表示
第六周 20/110 1/6 30/140 处理器体系结构
第七周 20/130 1/7 30/170 存储器层次结构
第八周 0/130 2/9 10/180 期中复习
第九周 48/178 1/10 10/190 系统级I/O、错误处理
posted @ 2016-11-12 11:13  20145308刘昊阳  阅读(152)  评论(1编辑  收藏  举报