20145314郑凯杰《信息安全系统设计基础》第9周学习总结 PART A

20145314郑凯杰《信息安全系统设计基础》第9周学习总结 PART A

明确教材学习目标

  • 注意每个系统调用的参数、返回值,会查帮助文档

  • 阅读教材,完成课后练习(书中有参考答案),考核:练习题把数据变换一下

  • 学习视频,掌握两个重要命令:

    man -k key1 | grep key2| grep 2 : 根据关键字检索系统调用
    grep -nr XXX /usr/include :查找宏定义,类型定义

  • 教材中相关代码运行、思考一下,读代码的学习方法见「代码驱动的程序设计学习」。

  • 代码重点:课程演示代码

教材学习内容总结

本章概述

①输入/输出(I/O)

是指主存和外部设备(如磁盘,终端,网络)之间拷贝数据过程。

Unix I/O

个Unix 文件就是一个m个字节的序列:

B0,B1,···,Bk,···,Bm-1

在UNIX系统中有一个说法,一切皆文件。所有的I/O设备,如网络、磁盘都被模型化为文件。而所有的输入和输出都被当做对相应文件的读和写来执行。这种将设备映射为文件的方式,允许UNIX内核引出一个简单、低级的应用接口,称为UNIX I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行。

  1. 打开文件 打开文件操作完成以后才能对文件进行一些列的操作,打开完成过以后会返回一个文件描述符,它在后续对此文件的所有操作中标识这个文件,内核记录有关这个打开文件的所有信息。
  2. 改变当前的文件位置。
  3. 读写文件
  4. 关闭文件 应用完成了对文件的访问之后,就通知内核关闭这个文件,内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。进程终止,内核也会关闭所有打开的文件并释放他们的存储器资源。

打开和关闭文件

int open(char *filename,int flags,mode_t mode);

其中打开标志flags有三种基本标志:

O_RDONLYO_WRONLYO_RDWR。也可以和其他三种(O_CREAT、O_TRUNC、O_APPEND)组合使用。

mode参数指定了新文件的访问权限位。(这次终于看到完全的mode参数的使用方法了)

图1:

读和写文件

在系统I/O中读写文件用的系统函数为read()write()函数来执行。

#include <unistd.h>

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

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

read函数从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。而write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。返回值要么为-1要么为写入的字节数目。

有些情况下,read和write传送的字节比应用程序要求的要少,出现这种情况的原因如下:

  • 读时遇到EOF。此时read返回0来发出EOF信号。
  • 从终端读文本行。如果打开文件是与终端相关联,那么每个read函数将以此传送一个文本行,返回的不足值等于文本行的大小。
  • 读和写网络套接字。可能会出现阻塞现象。

读取文件元数据

应用程序能够通过调用stat和fstat函数检索到关于文件的信息

#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函数只不过是以文件描述符而不是文件名作为输入。

共享文件

内核用三个相关的数据结构来表示打开的文件:

  • 描述符表(descriptor table)每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。
  • 文件表(file table) 打开文件的描述符表项指向问价表中的一个表项。所有的进程共享这张表。每个文件表的表项组成包括由当前的文件位置、引用计数(既当前指向该表项的描述符表项数),以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的应用计数。内核不会删除这个文件表表项,直到它的引用计数为零。
  • v-node表(v-node table)同文件表一样,所有的进程共享这张v-node表,每个表项包含stat结构中的大多数信息,包括st_mode和st_size成员。

图2:

描述符1和4通过不同的打开文件表表项来引用两个不同的文件。这是典型的情况,没有共享文件,并且每个描述符对应一个不同的文件。

图3:

多个描述符也可以通过不同的文件表表项来应用同一个文件。如果同一个文件被open两次,就会发生上面的情况。关键思想是每个描述符都有它自己的文件位置,所以对不同描述符的读操作可以从文件的不同位置获取数据。

图4:

父子进程也是可以共享文件的,在调用fork()之前,父进程如第一张图,然后调用fork()之后,子进程有一个父进程描述符表的副本。父子进程共享相同的打开文件表集合,因此共享相同的文件位置。一个很重要的结果就是,在内核删除相应文件表表项之前,父子进程必须都关闭了他们的描述符。

I/O使用的抉择方法

上图中展现了几种I/O的关系模式,在应用程序中应该使用哪些函数呢?标准I/O函数是磁盘和终端设备I/O的首选。但是对网络套接字上尽量使用健壮的RIO或者系统I/O

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第七周 1300/1750 11/11 140/140
第八周 1700/2000 13/13 160/160
第九周 2000/2400 14/15 180/180
第十周 2500/2800 15/17 0/200

参考资料

原文地址:https://www.cnblogs.com/5314zkj/p/6052730.html