zoukankan      html  css  js  c++  java
  • 20145301 《信息安全系统设计基础》第9周学习总结

    20145301 《信息安全系统设计基础》第9周学习总结

    教材学习内容总结

    第十章-系统级I/O

    10.1 Unix I/O
    • I/O设备:网络、磁盘和终端
    • Unix I/O :将设备映射为文件的方式,允许Unix内核引出一个简单、低级的应用接口。
    • 描述符:打开文件时,内核返回一个小的非负整数。
    • Unix外壳创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)、标准错误(描述符为2)。
    • 改变当前的文件位置:文件位置为k,初始为0。
    • seek操作:显式地设置文件的当前位置为k.
    • EOF:END OF FILE,是一个条件
    10.2 打开和关闭文件
    • open函数:打开一个已存在的文件或者创建一个新文件  
      #include <sys/types.h>  
      #include <sys/stat.h>  
      #include <fcntl.h>  
      int open(char *filename,int flags,mode_t mode);
    • open函数将filename转换为一个文件描述符,并且返回描述符数字。 返回的描述符总是在进程中当前没有打开的最小描述符。
    • filename:文件名

    • flags:指明进程打算如何访问这个文件,

      • O_ RDONLY :只读
      • O_ WRONLY :只写
      • O_ RDWR :可读可写
      • O_CREAT:文件不存在,就创建新文件
      • O_TRUNC:如果文件存在,就截断它
      • O_APPEND:写操作前设置文件位置到结尾处
    • flag参数可以是一个或多个更多位掩码的或。
      • O_ CREAT:如果文件不存在,就创建它的一个截断的空文件
      • O_ TRUNC:如果文件已经存在,就截断它
      • O_ APPEND:在每次写操作前,设置文件位置到文件的结尾处。
    • mode参数指定了新文件的访问权限位。文件的访问权限位被设置为mode & ~umask
    10.3 读和写文件
    • 应用程序是通过分别调用read和write函数来执行输入和输出的。  
      #include <unistd.h>  
      ssize_t read(int fd,void buf,size_t n);  
      ssize_t write(int fd,const void 
      buf,size_t n);
    • read函数:从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。 返回值:-1:一个错误;0:EOF;否则,返回值:实际传送的字节数量。

    • write函数:从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。

    • lseek函数:应用程序能够显式地修改当前文件的位置。

    • 不足值:read和write传送的字节比应用程序要求的少。

    • 产生不足值的原因:  
      1、读时遇到EOF  
      2、从终端读文本行  
      3、读和写网络套接字

      10.4 用RIO包健壮地读写
    • RIO包的实质:I/O包

    • RIO包提供的两种函数:无缓冲的输入输出函数、带缓冲的输入函数(线程安全)

    • RIO的带缓冲的输入函数

    一个文本行就是一个有换行符结尾的ASCII码字符序列。 在Unix系统中,换行符(‘ ’)与ASCII码换行符(LF)相同,数字值为0x0a。

    10.5 读取文件元数据
    • 检索文件信息(元数据):应用程序能够通过调用stat和fstat函数

    • stat函数以一个文件名作为输入,填写一个stat数据结构中的各个成员。

    • fstat函数以文件描述符而不是文件名作为输入。

    • st_ size成员包含了文件的字节数大小。

    • st_ mode成员则编码了文件访问许可位和文件类型。

    • 文件类型包括:

      • 普通文件:某种类型的二进制或文本数据。
      • 文件:关于其他文件的信息。
      • 套接字:一种用来通过网络与其他进程通信的文件。
      • 宏指令:根据st_mode成员来确定文件的类型。
    • 在sys/stat.h中定义:

      • S_ ISREG():这是一个普通文件吗?
      • S_ ISDIR():这是一个目录文件吗?
      • S_ ISSOCK():这是一个网络套接字吗?
    10.6 共享文件
    • 内核使用三个相关的数据结构来表示打开的文件:

      • 描述符表:每个进程都有它独立的描述符表。 每个打开的描述符表项指向文件表中的一个表项。
        • 文件表:所有进程共享这张表。每个文件表的表项组成包括有当前的文件位置、引用计数、以及一个指向v-node表中对应表项的指针。 直到引用计数为0,内核才会删除该文件表表项。
      • v-node表:所有进程共享这张v-node表。
    • 在内核删除相应文件表项之前,父子进程必须都关闭了它们的描述符。

    10.7 I/O重定向
    • Unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输入输出联系起来。

    unix> ls > foo.txt

    • I/O重定向是依靠dup2函数工作的。 #include <unistd.h>  
      int dup2(int oldfd,int newfd);
    • dup2函数拷贝描述符表表项oldfd到描述符表表项newfd,覆盖描述符表表项newfd以前的内容。若newfd已经打卡了。dup2会在拷贝oldfd之前关闭newfd。
    10.8 标准I/O
    • 标准I/O库将一个打开的文件模型化为一个流,一个流就是一个指向FILE类型的结构的指针。每个ANSIC程序开始都有三个打开的流stdin、stdout和stderr,分别对应于标准输入、标准输出、标准错误。

    • 类型为FILE的流是对文件描述符和流缓冲区的抽象。流缓冲区的目的和RIO读缓冲区的一样,就是开销较高的Unix I/O系统调用的数量尽量能的小。

    10.9 I/O函数的使用
    • 应用程序可以通过open、close、lseek、read、write和stat这样的函数来访问Unix I/O。

    • RIO函数:read和write的健壮的包装函数,自动处理不足值,为读文本行提供一种高效的带缓冲的方法。

    • 标准I/O函数:提供了Unix I/O函数的一个更加完整的带缓冲的替代品,包括格式化的I/O例程。是磁盘和终端设备I/O之选。
    • 套接字描述符:Unix对网络的抽象是一种称为套接字的文件类型,被称为套接字描述符。应用进程通过读写套接字描述符来与运行在其他计算机上的进程通信。

    • 对流I/O限制是:

      • 跟在输出函数之后的输入函数,必须在其中间插入fflush、fseek、fsetpos或者rewind函数,后三个函数使用Unix I/O中的lseek函数来重置当前的文件位置。

      • 跟在输入函数之后的输出函数,必须在中间插入fseek、fsetpos或者rewind的调用,一个输出函数不能跟随在一个输入函数之后,除非该输入函数遇到了一个EOF。

    • 解决对流I/O限制的方法是:  
      采用在每个输入操作前刷新缓存区这样的规则来满足。 对同一个打开的套接字描述符打开两个流,一个用来读,一个用来写。

    教材学习中的问题和解决过程

    • 10.1 编译时发现缺失“csapp.h”的一系列头文件,通过在CSDN.NET上找到了csapp.h和csapp.c,在网上下载,最终得到了正确答案:  
      fd2=3

    课后作业

    • 10.1

      • Unix进程生命周期开始时,打开的描述符赋给了stdin(描述符0)、stdout(描述符1)和stderr(描述符2)。因为fd1已经关闭,因此程序的输出是“fd2=3”。
    • 10.2

      • 描述符fd1和fd2都要各自的打开文件表表项,所以每个描述符对于foobar.txt都有它自己的位置。因此,从fd2的读操作会读取foobar.txt的第一个自己,并输出c=f ,而不是 c=o
    • 10.3

      • 子进程继承父进程的描述符表,以及所有进程共享的同一个打开文件表。描述符fd在父子进程中都指向同一个打开文件表表项。当子进程读取文件的一个字节时,文件位置加1.所以,父进程会读取第二个字节,而输出就是 c=o,而不是10.2中的 c=f
    • 10.4

      • 重定向标准输入(描述符0)到描述符5,直接调用dup2(5,0)
    • 10.5

      • fd1重定向到了fd2,输出应该为c=o

    本周代码托管截图

    学习进度条

     代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
    目标  4000行  24篇  400小时   
    第一周  150/150  1/1  15/15  对Linux有了初步的认识
    第二周  200/350 1/2 20/35 vim的使用 
    第三周  250/600 1/4 20/55 各种信息的表示方法
    第五周  250/850 1/5 25/80 汇编与反汇编
    第六周  150/1000 1/6 25/105 Y86
    第七周  74/1074 1/7 25/130 各类存储器
    第八周  0/1074  2/9 20/150 错题总结
    第九周  109/1183 2/11 25/175 系统级I/O

    参考资料

  • 相关阅读:
    go语言之goroute协程
    Vue中Computed和Watch的用法及区别
    php判断复选框是否被选中的方法
    基于workerman的实时推送
    织梦引入公共模板
    织梦快速建站首页模板
    golang解决中文乱码的方法
    Vue项目中使用可视化图表echarts
    解决for循环中异步请求顺序不一致的问题
    layui多图上传实现删除功能的方法
  • 原文地址:https://www.cnblogs.com/5301z/p/6059924.html
Copyright © 2011-2022 走看看