所有的I/O设备,如网络、磁盘都被模型化为文件,而所有的输入和输出都被当做对相应文件的读和写来执行。这种将设备映射为文件的方式,允许UNIX内核引出一个简单、低级的应用接口,称为UNIX I/O。
打开完成过以后会返回一个文件描述符,它在后续对此文件的所有操作中标识这个文件,内核记录有关这个打开文件的所有信息。
基本标志:O_RDONLY、O_WRONLY、O_RDWR,也可以和其他三种(O_CREAT、O_TRUNC、O_APPEND)组合使用。
应用完成了对文件的访问之后,就通知内核关闭这个文件,内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。进程终止,内核也会关闭所有打开的文件并释放他们的存储器资源。
从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。
从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。返回值要么为-1要么为写入的字节数目。
显示的修改当前文件位置。
a.读时遇到EOF。此时read返回0来发出EOF信号。
b.从终端读文本行。如果打开文件是与终端相关联,那么每个read函数将以此传送一个文本行,返回的不足值等于文本行的大小。
c.读和写网络套接字。可能会出现阻塞现象。
提供了两类不同的函数:
无缓冲的输入输出函数 直接在存储器和文件之间传送数据。
带缓冲的输入函数
1.从描述符fd的当前文件位置最多传送n个字节到存储器位置usrbuf。
2.遇到EOF只能返回一个不足值。
1.从位置usrbuf传送n个字节到描述符fd。
2.绝不会返回一个不足值。
对同一个描述符,可以任意交错地调用rio_readn和rio_writen。
编写计算文本文件中文本行的数量如何实现?
1.read函数,一次一个字节从文件传送到用户存储器,检查每个字节来查找换行符。(效率低)
2.rio_realineb包装函数,从一个内部读缓冲区拷贝一个文本行,当缓冲区变空时,会自动调用read重新填满缓冲区。
1.从文件rp读出一个文本行,将它拷贝到存储器位置usrbuf,并用空字符结束这个文本行。
2.最多读maxlen-1个字节,余下的一个字符留给结尾的空字符串。
1.应用程序能够通过调用stat和fstat函数检索到关于文件的信息。
2.stat以一个文件名为输入,并且填充buf结构体。
3.fstat函数只不过是以文件描述符而不是文件名作为输入。
* 内核用三个相关的数据结构来表示打开的文件
a.描述符表。表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。
b.文件表。每个文件表的表项组成包括由当前的文件位置、引用计数以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的应用计数。内核不会删除这个文件表表项,直到它的引用计数为零。
c.v-node表。所有的进程共享这张v-node表,每个表项包含stat结构中的大多数信息,包括st_mode和st_size成员。
描述符1和4通过不同的打开文件表表项来引用两个不同的文件。
多个描述符也可以通过不同的文件表表项来应用同一个文件。
调用fork()之后
子进程有一个父进程描述符表的副本。父子进程共享相同的打开文件表集合,因此共享相同的文件位置。一个很重要的结果就是,在内核删除相应文件表表项之前,父子进程必须都关闭了他们的描述符。
* dup2函数拷贝描述符表表项oldfd到描述符表表项newfd,覆盖描述符表表项newfd以前的内容。如果newfd已经打开了,dup2会在拷贝oldfd之前关闭newfd。
解决:缺少头文件。起初是把“csapp.h”换成open函数的头文件。
小组中同学详细的解答了这个问题,是缺少动态库。(ls视频中讲到了)
估计学习时间:5小时
实际学习时间:7小时
看书:2小时
代码:3.5小时
博客:1.5小时
《深入理解计算机系统》
ls.tar视频
http://group.cnblogs.com/topic/73278.html
http://www.cnblogs.com/ZhangShuo/articles/1829589.html
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。