第十章学习笔记总结

10.1 Unix I/O

一个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

 

posted @ 2015-11-08 18:35  20135221黄卫  阅读(236)  评论(0编辑  收藏  举报