20145223《信息安全系统设计基础》第9周学习总结
2016-11-13 17:05
369 查看
20145223 《信息安全系统设计基础》第9周学习总结
教材学习内容总结——系统级I/O
1.输入/输出(I/O)是在主存和外部设备(如磁盘驱动器、终端和网络)之间拷贝数据的过程。输入就是从I/O设备拷贝数据到主存,而输出就是从主存拷贝数据到I/O设备。所有语言的运行时系统都提供执行I/O的较高级别的工具。例如,ANSI C提供标准I/O库,包含像printf和scanf这样执行带缓冲区的I/O函数。C++语言用它的重载操作符<<(输出)和>>(输入)提供了类似的功能。在UNIX系统中,是通过使用由内核提供的系统级Unix I/O函数来实现这些比较高级的I/O函数的。
2. Unix I/O——每个unix文件都是一个m字节的序列,所有I/O设备如网络、磁盘和终端都被模型化为文件,而输入和输出就是对这些文件的读写操作。
(1)打开文件:一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备,内核返回一个**小的非负整数**,叫做**描述符**。 //unix系统创建每个进程的时候都有三个打开的文件:标准输入(描述符0);标准输出(描述符1),标准错误(描述符2)。 (2)改变当前的文件位置:对于每个打开的文件,内核保持着一个文件位置k(从文件开头起始的字节偏移量)。 (3)读写文件。读操作就是从文件拷贝n>0个字节到存储器,从当前文件位置k开始,然后将k增加到k+n。给定一个m字节的文件,当k>=m时执行读操作会触发一个称为end-of-file(EOF)的条件 (4)关闭文件。应用通知内核关闭这个文件;作为响应,内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池当中。
3.打开和关闭文件
进程是通过调用open函数来打开一个已存在的文件或者创建一个新文件:
#include <sys/type.h>' #include <sys/stat.h>' #include <fcntl.h>` int open(char *filename, int flags, mode_t mode);` //返回:若成功则为新文件描述符,若出错为-1.
open函数将filename转换为一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中当前没有打开的最小描述符。flags参数指明了进程打算如何访问这个文件:
fd=Open("foo.txt",O_RDONLY,0);如何以读的方式 打开一个已存在的文件
//flags参数也可以是一个或者更多位掩码的或,提供一些额外的指示。 O_RDONLY:只读。 O_WRONLY:只写。 O_RDWR:可读可写。
fd=Open("foo.txt",O_WRONLY|O_APPEND,0);//打开一个已存在的文件并在后面添加一些数据
·-O_CREAT:如果文件不存在,就创建他的一个截断的(truncated)(空)文件。 ·-O_TRUNC:如果文件已经存在,就截断它。 ·-O_APPEND:在每次写操作前,设置文件位置到文件的结尾处。 //mode参数指定新文件的访问权限位。作为上下文的一部分,每个进程都有一个umask;当进程通过带某个带mode参数的open函数用来创建一个新文件的时候,文件的访问权限位被设置为mode & ~umask。 以上为访问权限位。在sys/stat.h中定义。
最后进程调用close()关闭一个打开的文件
#include<unistd.h> int close(int fd);//若成功则返回0,不成功则为-1。
4. 读和写文件
应用程序是通过分别调用read和write函数来执行输入和输出的。
#include <unistd.h> read函数从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf,返回值-1表示一个错误。而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。 ssize_t read(int fd,void *buf,size_t n);//返回值:成功为读的字节数,若EOF为0,出错为-1` write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。 ssize_t write(int fd,const void *buf,size_t n);// 返回值成功为写的字节数,出错为-1
#include "csapp.h" int main(void) { char c; while(Read(STDIN_FILENO, &c, 1) != 0) Write(STDOUT_FILENO, &c, 1); exit(0); }
read函数从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。 - 在某些情况下,read和write传送的字节比应用程序要求的要少。出现这种情况的可能的原因有:
读时遇到EOF。假设该文件从当前文件位置开始只含有20个字节,而应用程序要求我们以50个字节的片进行读取,这样一来,这个read的返回的值是20,在此之后的read则返回0。 从终端读文本行。如果打开的文件是与终端相关联的,那么每个read函数将一次传送一个文本行,返回的不足值等于文本行的大小。 读和写socket。如果打开的文件对应于网络套接字,那么内部缓冲约束和较长的网络延迟会导致read和write返回不足值。
5.用RIO包健壮地读写
RIO提供了两类不同的函数:(1)无缓冲的输入输出函数 (2)带缓冲的输入函数
无缓冲的输入输出函数:(通过调用rio_writen和rio_readn函数,应用程序可以在存储器和文件之间直接传送数据)
#inluude<csapp.h> ssizet rio_writen(int fd,const void *usrbuf,size_t n); ssizet rio_writen(int fd,const void *usrbuf,size_t n); //rio__writen函数遇到EOF的时候返回0; //rio__readn遇到EOF的时候返回不足值(即 不足n的那个部分的字节数)。
带缓冲的输入函数:允许用户高效地从文件中读取文本行和二进制数据(之前是一次读一个字节,应用这个函数之后,可以一次读一行函数)。
原理:函数从内部缓冲区中拷贝一个文本行,当缓冲区变空的时候,会自动地调用read重新填满缓冲区。6.取文件元数据(文件信息)
应用程序能够通过调用stat和fstat函数检索到关于文件的信息(有时也称为文件的元数据medatada)
#include <sys/stat.h> #include <unistd.h> int stat(const char *filename,struct stat *buf); int fstat(int fd,struct stat *buf);//若成功,返回0,若出错则为-1
stat以一个文件名为输入,并且填充buf结构体。fstat函数只不过是以文件描述符而不是文件名作为输入。
其中st_size成员包含了文件的字节大小。st_mode为文件访问许可位。
UNIX提供的宏指令根据st_mode成员来确定文件的类型: | |
---|---|
S_ISREG() | 这是一个普通文件么; |
S_ISDIR() | 这是一个目录文件么; |
S_ISSOCK() | 是一个网络套接字么。 |
/* $begin statcheck */ #include "csapp.h" int main (int argc, char **argv) { struct stat stat; char *type, *readok; /* $end statcheck */ if (argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(0); } /* $begin statcheck */ Stat(argv[1], &stat); if (S_ISREG(stat.st_mode)) /* Determine file type */ type = "regular"; else if (S_ISDIR(stat.st_mode)) type = "directory"; else type = "other"; if ((stat.st_mode & S_IRUSR)) /* Check read access */ readok = "yes"; else readok = "no"; printf("type: %s, read: %s\n", type, readok); exit(0); } /* $end statcheck */
7.共享文件
内核用三个相关的数据结构来表示打开的文件:
描述符表(descriptor table):每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。 文件表(file table): 打开文件的描述符表项指向问价表中的一个表项。所有的进程共享这张表。每个文件表的表项组成包括由当前的文件位置、引用计数(既当前指向该表项的描述符表项数),以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的应用计数。内核不会删除这个文件表表项,直到它的引用计数为零。 v-node表(v-node table):同文件表一样,所有的进程共享这张v-node表,每个表项包含stat结构中的大多数信息,包括st_mode和st_size成员。
书上p607三中打开文件的类型
每周测试错题问题解决:
问题1:Linux中查找配置(configure)网卡(interface)的命令是(man –k configure | grep interface )
命令运行结果:
问题2:git log 命令来查看(提交历史)
命令运行结果:
本周代码托管截图
- 代码托管链接
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 4000行 | 20篇 | 400小时 | |
第0周 | 0/0 | 1/1 | 5/5 | |
第1周 | 0/0 | 1/2 | 10/15 | |
第2周 | 300/300 | 1/3 | 15/30 | |
第3周 | 200/500 | 1/4 | 10/40 | |
第5周 | 150/650 | 1/5 | 10/50 | |
第6周 | 50/700 | 1/6 | 8/58 | |
第7周 | 0/700 | 1/7 | 8/64 | |
第8周 | 0/700 | 2/9 | 5/70 | |
第7周 | 181/881 | 2/11 | 7/77 |
参考资料
《深入理解计算机系统V2》学习指导...
相关文章推荐
- 20145223《信息安全系统设计基础》第3周学习总结
- 20145322学号 《信息安全系统设计基础》第9周学习总结(一)
- 20145334《信息安全系统设计基础》第9周学习总结
- 20144303《信息安全系统设计基础》第9周学习总结
- 20145231 《信息安全系统设计基础》第9周学习总结
- 20145223《信息安全系统设计基础》第5周学习总结
- 20145306《信息安全系统设计基础》第9周学习总结
- 20145205 《信息安全系统设计基础》第9周学习总结
- 20145212 《信息安全系统设计基础》第9周学习总结
- 20145325张梓靖 《信息安全系统设计基础》第9周学习总结
- 20145239 《信息安全系统设计基础》第9周学习总结
- 20145305 《信息安全系统设计基础》第9周学习总结
- 20145214 《信息安全系统设计基础》第9周学习总结
- 20145223《信息安全系统设计基础》第6周学习总结
- 20145223《信息安全系统设计基础》第0周学习总结
- 20145314郑凯杰《信息安全系统设计基础》第9周学习总结 PART A
- 20145308 《信息安全系统设计基础》第9周学习总结
- 20145335郝昊 《信息安全系统设计基础》第9周学习总结
- 20145221 《信息安全系统设计基础》第9周学习总结
- 20145317《信息安全系统设计基础》第9周学习总结2