第十章、系统I/O

一个Unix文件就是一个m个字节的序列:B0,B1,…,BK,…,Bm-1

一、unix i/o 596

Unix I/O:一种将设备优雅地映射为文件的方式,允许Unix内核引出一个简单、低级的应用接口,这使得所有的输入输出都能以一种统一且一致的方式来执行:

**1.打开文件:** - 内核返回一个小的非负整数,叫做描述符。 -Unix外壳创建的每个进程开始时都有三个打开的文件:标准输入(描述符 为0)、标准输出(描述符为1)、标准错误(描述符为2)。 

2.改变当前文件位置:

对于每个打开的文件,内核保持着一个文件位置K,初始为0。 这个文件位置是从文件开头起始的字节偏移量。应用程序能够通过执行seek操作,显示地设置文件当前位置为K。 

3.读写文件:

读操作:从文件拷贝n>0个字节到存储器,从当前文件位置K开始,然后将K增加到k+n。 写操作:从存储器拷贝n>0个字节到一个文件,从当前文件位置K开始然后更新K 。 

4.关闭文件:

二、打开和关闭文件

open函数将filename转换成一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中没有打开的最小描述符。

Flags参数指明了进程打算如何访问这个文件:

  • O_RDONLY:只读
  • O_WRONLY:只写
  • O_RDWR:可读可写

Flags参数也可以是一个或者更多位掩码的或,为写提供给一些额外的指示:

  • O_CREAT:如果文件不存在,就创建它的一个截断的(空)文件。
  • O_TRUNC: 如果文件已经存在,就截断他。
  • O_APPEN D:在每次写操作前,设置文件位置到文件的结尾处。

Mode参数指定了新文件的访问权限位。

三、读和写文件

read (int fd, void *buf, size_t n)(返回:若成功,则为读的字节数,若EOF则为0,若出错则为-1)  write(int fd, const void *buf, size_t n)(返回:若成功则为写的字节数,若出错则为-1) 

旁注:sizet是作为usigned int,而ssizet是作为int。

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

读时遇到EOF。假设该文件从当前文件位置开始只含有20个字节,而应用程序要求我们以50个字节的片进行读取,这样一来,这个read的返回的值是20,在此之后的read则返回0。 从终端读文本行。如果打开的文件是与终端相关联的,那么每个read函数将一次传送一个文本行,返回的不足值等于文本行的大小。 读和写socket。如果打开的文件对应于网络套接字,那么内部缓冲约束和较长的网络延迟会导致read和write返回不足值。

四、用rio包健壮地读写

RIO包会自动为你处理上文中所述的不足值。

RIO提供了两类不同的函数:

  • 无缓冲的输入输出函数。
  • 带缓冲的输入函数。 10.4.1 RIO的无缓冲的输入输出函数

通过调用rioreadn和riowriten函数,应用程序可以在存储器和文件之间直接传送数据。

五、读取文件元数据

文件的元数据,就是关于文件的信息。

int stat(const char *filename, struct stat *buf); int fstat(int fd, struct stat *buf); 

讨论Web服务器时,会需要stat数据结构中的stmode和stsize成员。st_mode则编码了文件访问许可位和文件类型。

Unix提供的宏指令根据st_mode成员来确定文件的类型。

  • S_ISREG() 普通文件
  • S_ISDIR() 目录文件
  • S_ISSOCK() 套接字

stat数据结构中的成员。重点掌握stmode,stsize.

     st_size:文件字节数大小       st_mode:文件访问许可位和文件类型。(普通文件:二进制文件和文本文件。目录文件:其他文件信息。套接字:通过网络与其他进程通信的文件。) 

六、共享文件

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

               描述符表:每个打开的描述符表项指向文件表中的一个表项。                 文件表:打开的文件的集合是由一张文件表表示的,所有的进程共享这张表。包括文件位置、引用计数(当前指向该表项的描述符表项数),指向v-node表的指针。                 v-node表:包含stat结构中大多数信息。 

打开文件的内核数据结构

文件共享。共享了同一个磁盘文件

子父进程共享文件。子进程有一个父进程描述表符副本,所以他们共享打开文件的集合。注意,在内核删除相应文件表表项之前,子父进程必须都关闭他们的描述符。

七、I/O重定向

方法一:使用dup2函数 dup2函数拷贝了描述符表表项oldfd到描述符表项newfd,覆盖描述符表项newfd的内容。若果newfd已经打开了,dup2会拷贝oldfd之前关闭newfd.

标准的I/O 标准I/O库将一个打开的文件模型化为一个流,一个流就是一个指向FILE类型的结构指针,。stdin\stdout\stdeer分别对应标准输入、标准输出、标准错误。

extern FLIE *stdin extern FILE *stdout extern FILE *stderr 

类型为FILE的流是对文件描述符和流缓冲区的抽象。

问题及解决

1、不理解dup2函数的工作原理

通过搜索资料:

定义这个函数的头文件是unistd.h,有兴趣的可以自己看看这个头文件包含的内容

  要提的是这个头文件同时定义了下面三个常量 

STDERRFILENO = 2 标准错误输出 STDINFILENO = 0 标准输入 STDOUT_FILENO = 1 标准输出 兄弟们学习网络编程用0,1,2这些参数的时候也得知道代表的意思

  要说这两个函数的意思,还是看一段具体的代码 

int fd, fd2;
modet fdmode = SIRUSR|SIWUSR|SIRGRP|SIROTH;

void redir_stdout(const char *filename)
{
fd2=dup(STDOUTFILENO);
fd = open(filename, O
WRONLY|O_CREAT, fdmode); //打开文件操作 dup2(fd, STDOUTFILENO); //把输出重定向到fd标识的文件 close(fd);
}

  fd2=dup(STDOUT_FILENO);说明fd2表示了标准输出   如果我们想把刚刚定向到fd的输出,再定向回标准输出,我们可以用下面的代码实现: 

void resumestdout() //恢复输出,把标准输出定向到fd2,fd2代表的是标准输出 {
dup2(fd2, STDOUT
FILENO); 
close(fd2);
}

参考资料

[1]《深入理解操作系统》 [2]http://www.cnblogs.com/lalacindy/p/4933184.html [3]百度百科http://baike.haosou.com/doc/5948579-6161518.html

转载于:https://www.cnblogs.com/L20135304/p/4948716.html

20135304刘世鹏——信息安全系统设计基础第九周总结相关推荐

  1. 20135304刘世鹏——信息安全系统设计基础第一周学习总结

    第一节 Linux系统简介 一.Linux是一个操作系统 1. Linux 本身只是操作系统的内核.内核是使其他程序能够运行的基础. 它实现了多任务和硬件管理,用户或者系统管理员交互运行的所有程序 实 ...

  2. 20135219洪韶武——信息安全系统设计基础第九周学习总结

    信息安全系统设计基础第九周学习总结 学习时间:7小时 学习内容:课本第十章 一.第十章知识点(1~6) 第一部分:文件的概念及相关操作 1.每个unix文件都是一个m字节的序列:所有I/O设备如网络. ...

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

    第十章 系统级I/O的实践 学习目标: 代码阅读理解: 1.编译运行代码 2.使用man学习理解相关系统调用, 理解参数.返回值的含义 3.会用grep -nr xxx /usr/include 查宏 ...

  4. 信息安全系统设计基础第九周总结

    第十章 系统级I/O 输入操作是从I/O设备拷贝数据到主存,输出操作是从主存拷贝数据到I/O设备 10.1Unix I/O 一个Unix文件就是一个m个字节的序列: 所有的I/O设备都被模型化为文件, ...

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

    学习计时:共15小时 读书:1 代码:10 作业:13 博客:1 一.学习目标 1. 能够独立安装Linux操作系统 2. 能够熟练使用Linux系统的基本命令 3. 熟练使用Linux中用户管理命令 ...

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

    信息安全系统设计基础第二周学习总结 学习目标 1. 熟悉Linux系统下的开发环境    2. 熟悉vi的基本操作    3. 熟悉gcc编译器的基本原理    4. 熟练使用gcc编译器的常用选项 ...

  7. 模块20135304——刘世鹏

    编译生成新内核 一.实践原理 Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个单内核.单内核由于所有内容都集成在一起,效率很高,但可扩展 ...

  8. 20135323符运锦---信息安全系统设计基础第一周学习总结

    学习计时:共15小时 读书:1小时 代码:8小时 作业:4小时 博客:2小时 一.学习目标 1. 能够独立安装Linux操作系统   2. 能够熟练使用Linux系统的基本命令   3. 熟练使用Li ...

  9. LINUX信息安全系统设计基础第一周学习总结

     Linux系统简介 一.实验内容 了解 Linux 的历史,Linux 与 Windows 的区别等入门知识. 二.实验要求 阅读linux简介与历史 三.实验步骤 二.Linux 与 Window ...

最新文章

  1. 收藏 | Google 发布关于机器学习工程的最佳实践
  2. ROM,RAM,DRAM,SDRAM,SRAM
  3. 利用正则表达式去掉html代码
  4. 32f407tim4时钟源频率_STM32学习笔记04—SysTick时钟
  5. flex 布局以及样式
  6. Eigen(3)矩阵Matrix及其简单操作
  7. python大数据零基础_零基础学习大数据人工智能,学习路线篇!
  8. python语言的基础知识_pythone语言基础知识汇总
  9. Cosmos OpenSSD--greedy_ftl1.2.0(二)
  10. mysql 字节流_字节流至缓冲流
  11. php结构的项目,ThinkPHP修改项目结构
  12. 一份比较详尽的ubuntu下替代windows下的软件列表
  13. 鹏业软件CAD云服务转图纸没反应的说明
  14. OpenGL法线贴图
  15. Django框架_day01
  16. linux 系统下关闭屏幕
  17. 侯捷先生的Design Patterns高级课程
  18. LeetCode二叉树系列——515.最每个树行中找最大值
  19. 由13位数字组成的中国标准书号校验码计算实例
  20. 网络营销实战课-微信实操

热门文章

  1. C++ vector 容器的使用
  2. python time模块和random 模块
  3. python之循环(增删)内使用list.remove()
  4. 那些前端应该知道的HTTP知识
  5. PNG和PVR之间互相转换的脚本
  6. WAV音频格式解析C代码
  7. RHEL 4 安装单实例oracle 10g
  8. PropertyGrid 绑定动态的属性与值的集合
  9. [转载].一直不怎么明白PID的运算输出结果怎么换算成执行机构的控制量
  10. asp ado 连接测试_ASP.NET Core 简介