信息安全系统设计基础第九周学习总结

系统级I/O

10.1 UNIX I/O

1.打开文件:一个应用程序要访问一个I/O设备,即要求内核打开相应文件。

2.描述符:内核返回一个小的非负整数,在后续对此文件的所有操作中标识这个文件。

  • 标准输入(描述符0):STDIN_FILENO

  • 标准输出(描述符1):STDOUT_FILENO

  • 标准错误(描述符2):STDERR_FILENO

3.文件位置:从文件开头起始的字节偏移量k。应用程序能够通过执行seek操作,显式设置文件当前位置

10.2 打开和关闭文件

1.flags:

  • O_RDONLY:只读

  • O_WRONLY:只写

  • O_RDWR:可读可写

2.mode:mode与umask共同指定了新文件的访问权限位。

3.文件的访问权限位:mode & ~umask

umask:umask需要在打开文件前使用函数umask(umask);进行设置

10.3 读和写文件

1.返回:若成功则为实际传送的字节数量;-1表示错误;0表示EOF

fd:源文件的描述符

n:拷贝最多n个字节

buf:目标存储器位置

ssize_t write(int fd,const void *buf, size_t n);

2.返回:若成功则为实际写的字节数量;-1表示错误

buf:源存储器位置

n:拷贝最多n个字节

fd:目标文件的描述符

不足值出现情况:

读时遇到EOF

从终端读文本行

读和写网络套接字

10.4 用RIO包健壮地读写

RIO包会自动处理不足值。RIO提供了两类不同的函数:

无缓冲的输入输出函数。这些函数直接在存储器和文件之间传送数据,没有应用级缓冲,他们对将二进制数据读写到网络和从网络读写二进制数据尤其有用。

带缓冲的输入函数。这些函数允许你高效地从文件中读取文本行和二进制数据,这些文件的内容缓存在应用级缓冲区内,类似于像printf这样的标准I/O函数提供的缓冲区。是线程安全的,它在同一个描述符上可以被交错地调用。例如,可以从一个描述符中读一些文本行,然后读取一些二进制数据,接着再多读取一些文本行。

1.无缓冲输入输出:

#include “csapp.h”
ssize_t rio_readn(int fd, void usrbuf, size_t n);
ssize_t rio_writen(int fd, void usrbuf, size_t n);
返回:
成功:传送的字节数

EOF:0

出错:-1

2.带缓冲的输入函数:

文本行:一个由换行符(0x0a)结尾的ASCII码字符序列

每打开一个描述符都会调用一次rio_readinitb函数,将描述符fd和地址rp处的一个类型为rio_t的读缓冲区联系起来

void rio_readinitb(rio_t *rp, int fd);

rio_readlineb函数从文件rp读一个文本行(包括换行符),到存储器位置usrbuf,用空字符结束文本行。至多读maxlen-1个字节,余下一个字符留给结尾空字符。超过maxlen-1部分会被截断。
ssize_t rio_readlineb(rio_t rp,void usrbuf, size_t maxlen);

rio_readnb从文件rp最多读n个字节到存储器位置usrbuf。
ssize_t rio_readnb(rio_t rp,void usrbuf, size_t n);

返回:

成功:读的字节数

EOF:0

出错:-1

对同一描述符,带缓冲区的函数调用可以任意交叉进行,但他们和无缓冲的调用不应交叉使用。

10.5 读取文件元数据

#include
#include <sys/stat.h>

int stat(const filename, struct stat buf);
int fstat(int fd, struct *buf);
返回:成功为0;出错为-1

stat以文件名为输入,fstat以文件描述符为输入。

10.6 共享文件

  • 没有共享文件,每个描述符对应一个不同文件。
  • 多个描述符也可以通过不同的文件表表项来引用同一个文件。(每个描述符都有自己的文件位置,所以对不同描述符的读操作可以从文件的不同位置获取数据)
  • 父子进程可以共享文件。子进程会有一个父进程描述符表项的副本,父子进程打开相同的文件表集合,共享相同的文件位置。在内核删除相应的文件表表项之前,父子进程都必须关闭相应的描述符表项。
  • 文件表:当前文件位置,引用计数(当前指向该表项的描述符项数),以及一个指向V-node表对应表项的指针
  • v-node表:包括st_mode和st_size成员

10.7 I/O重定向

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

参考资料:

1.《深入理解计算机系统》(第二版)

2.20135319朱锂的博客http://www.cnblogs.com/20135319zl/p/4945581.html

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