第十章学习笔记总结

发布于 2019-09-26 作者 风铃 4次 浏览 版块 前端

    <h1 class=\"postTitle\">
        <a id=\"cb_post_title_url\" class=\"postTitle2\" href=\"http://www.cnblogs.com/hw00332012/p/4947839.html\">第十章学习笔记总结</a>
    </h1>
    <div class=\"clear\"></div>
    <div class=\"postBody\">
        <div id=\"cnblogs_post_body\"><h1 id=\"unix-io\">10.1 Unix I/O</h1>

一个Unix文件就是一个m个字节的序列,所有的I/O设备都被模型化为文件,所有的输入和输出都被当做对应的文件的读和写操作来执行。



  • 打开文件


一个应用程序通过要求内核打开相应的文件,来宣告他想要访问一个I/O设备,内核返回一个小的非负整数叫做描述符,他在后续对此文件的所有操作中标识这个文件,内核记录有关这个打开文件的所有信息,应用程序只需记住这个描述符。


Unix外壳创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0),标准输出(1),标准错误(2)。



  • 改变当前的文件位置


对于每个打开的文件,内核保持着一个文件位置k,初始为0,这个文件位置时从文件开头起始的字节偏移量,应用程序能够通过执行seek操作,显式地设置文件的当前位置为k。



  • 读写文件


一个读操作就是从文件拷贝n>0个字节到存储器,从文件位置k开始,然后将k增加到k+n。给定一个大小为m字节的文件,当k≥m时执行读操作会触发一个EOF条件,检测到这个条件。类似的写操作就是存存储器拷贝n>0个字节到一个文件,从当前文件位置k开始然后更新k。



  • 关闭文件


当应用完成了对文件的访问之后,他就通知内核关闭这个文件,作为响应,内核释放文件打开是创建的数据结构,并将这个描述符恢复到可用的描述符池中,无论一个进程因为何种原因终止时,内核都会关闭所有打开的文件并释放他们的存储器资源。


10.2 打开和关闭文件


flags参数指明进程如何访问文件




  • O_RDONLY:只读




  • O_WRONLY:只写




  • O_RDWR:可读可写




flags参数也可以是一个或者更多位掩码的或:




  • O_CREAT:如果文件不存在,就创建他的一个截断的空文件




  • O_TRUNC:如果文件已经存在就截断它




  • O_APPEND:在每次写操作前,设置文件位置到文件的结尾处




10.3  读和写文件




  • read函数




从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。



  • write函数


从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。返回值要么为-1要么为写入的字节数目。




  • lseek函数




显示的修改当前文件位置。



  • 出现不足值的情况

  • a.读时遇到EOF。此时read返回0来发出EOF信号。

  • b.从终端读文本行。如果打开文件是与终端相关联,那么每个read函数将以此传送一个文本行,返回的不足值等于文本行的大小。

  • c.读和写网络套接字。可能会出现阻塞现象。


10.4 用RIO包健壮地读写



  • 提供了两类不同的函数:


无缓冲的输入输出函数 直接在存储器和文件之间传送数据。
带缓冲的输入函数


  • rio_readn函数


1.从描述符fd的当前文件位置最多传送n个字节到存储器位置usrbuf。


2.遇到EOF只能返回一个不足值。



  • rio_writen函数


1.从位置usrbuf传送n个字节到描述符fd。


2.绝不会返回一个不足值。




  • 对同一个描述符,可以任意交错地调用rio_readn和rio_writen。




  • 编写计算文本文件中文本行的数量如何实现?




  1.read函数,一次一个字节从文件传送到用户存储器,检查每个字节来查找换行符。(效率低)
2.rio_realineb包装函数,从一个内部读缓冲区拷贝一个文本行,当缓冲区变空时,会自动调用read重新填满缓冲区。


  • rio_realineb


1.从文件rp读出一个文本行,将它拷贝到存储器位置usrbuf,并用空字符结束这个文本行。


2.最多读maxlen-1个字节,余下的一个字符留给结尾的空字符串。


10.5  读取文件元数据


元数据:应用程序能够通过调用stat和fstat函数,检索到关于关于文件的信息,如创建时间,修改时间,metadata。




  1.  #include <unistd.h>
    #include <sys/stat.h>
    int stat(const char *filename, struct stat *buf);
    int fstat(int fd, struct stat *buf);
    返回: 若成功则为0,若出错则为-1.

    Stat函数以一个文件名作为输入,ftast以文件描述符作为输入。





              




  1. 函数是线程安全的:它在同一个描述符上可以被交替地调用。




10.6   共享文件




  1. 对于内核而言,文件文件和二进制文件毫无区别。




  2. 共享文件




内核用三种相关的数据结构来表示打开的文件。



  • 1)描述符表:它的表项由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个选项。
    2)文件表:打开文件的集合是一张文件表来表示的,所有的进程共享这张表。包括当前的文件位置、引用计数以及一个指向v-node表中对应表项的指针。
    3)v-node表:同文件表一样,所有的进程共享这张v-node表。每个表项包含stat结构中的大部分信息,包括st_mode和st_size成员。


             


               


                  


 


10.7 I/O重定向


unix>LS>foo.txt


使外壳加载和执行ls程序,将标准输出定向到磁盘文件


 


遇到的问题及解决办法:


unix提供了少量的系统级函数,它们允许用用程序打开、关闭、读和写文件,提取文件的元数据,以及执行I/O重定向,unix的读和写操作会出现不足值,出现此类情况,书上说使用RIO包,RIO包通过反复执行读写操作,其会自动处理不足值。但是在我的电脑系统上并没有自动处理该不足值


 


参考资料:《深入理解计算机中的 csapp,h和csapp.c》 http://www.cnblogs.com/LZYY/p/3423594.html


http://www.cnblogs.com/lhc-java/p/4941254.html


 










    </div>
    <div class=\"postDesc\">posted @ <span id=\"post-date\">2015-11-08 18:35</span> <a href=\"http://www.cnblogs.com/hw00332012/\">20135221黄卫</a> 阅读(<span id=\"post_view_count\">...</span>) 评论(<span id=\"post_comment_count\">...</span>)  <a href=\"http://i.cnblogs.com/EditPosts.aspx?postid=4947839\" rel=\"nofollow\">编辑</a> <a href=\"#\" onclick=\"AddToWz(4947839);return false;\">收藏</a></div>
收藏
暂无回复