本章节主要讲了 Linux 系统下的关于文件I/O操作的几个函数:open、read、write、lseek、close 的使用和需要注意的一些细节。接着,又介绍了多进程见如何共享文件。下面开始知识点梳理。

文件描述符

对于内核来说,所有打开的文件,都是通过文件描述符来引用。当打开或创建一个新的文件的时候,内核都会向进程返回该文件的文件描述符。文件描述符是什么,可以参考维基百科——文件描述符。UNIX 系统按惯例,会将0与进程的标准输入关联,将1与进程的标准输出关联,将2与进程的标准错误关联。

open 与 openat 函数的使用

  • oflag 参数:
    是通过在头文件 <fcntl.h> 中定义的常量中的一个或多个进行 “或”运算构成的。这里不再一一详述每个常量及其含义,感兴趣的小伙伴可以自行去查阅。
  • path 参数:
    是要打开和创建文件的名字。
  • fd 参数:
    fd 把open 和 openat 函数区分开来,具体有三种可能:

    1. 当path是绝对路径时, openat 就相当于是 open;
    2. path制定的是相对路径名称时,fd指出了相对路径名称的在文件系统中的开始位置;
    3. path是相对路径,fd参数具有特殊值 AT_FDCWD。此时,路径名在当前工作目录中获取,openat 函数在操作上与 open 函数类似;
      本节还讲到了 TOCTTOU 思想以及文件名与路径名被截断的问题。

creat 函数


creat函数是以只写的形式来打开一个新的文件的。

close 函数


关闭一个文件,会关闭该进程在当前文件上加的所有记录锁。一个进程结束之后,内核会自动关闭其打开的所有文件。

lseek 函数


lseek 函数仅会将当前的文件偏移量记录到内核中,其不会引起任何 I/O 操作。该偏移量是用来进行下一次读或者写的游标。偏移量的大小可以与文件实际大小不对应。当大于文件当前的实际长度的时候,对该文件的下一次写将加长该文件,且会形成一个空洞。位于文件中但是没有写过的字节都读为0。具体什么是空洞,可以看下百科——文件空洞

read 函数


如果 read 成功,则会返回读到的字节数。如果已经读到了文件的末尾,会返回0。

write 函数


对于普通文件,通常从当前的偏移量开始;如果在打开文件的时候,指定了 O_APPEND操作,则在每次写操作之前,将文件的偏移量设置在文件的末尾。每次写成功,文件的偏移量都会变化。

I/O 效率

大多数文件系统为改善性能,都会增加“预读”技术。当检测到正在进行顺序读取时,系统就试图读入比实际锁要求更多的数据。

文件共享

UNIX 系统支持不同进程之间共享打开文件。内核使用三种数据结构用来表示打开文件:
(1)每个进程在进程记录表中都会有一个记录项,记录项中包含一张打开文件描述符表。有每个文件描述符相关联的是:
A)文件描述符标志;
B)指向一个文件表项的指针;
(2)内核为所有打开文件维持一张文件表,每个文件表项包含:
A)文件状态标志;
B)当前文件的偏移量;
C)指向该文件v节点表项的指针;
(3)每个打开文件(或设备)都有一个v节点结构。


该图显示了一个进程打开多个文件的场景。打开文件描述符表可以存放在用户空间,而非进程表中。

该图展示了多个独立的进程打开同一个文件的场景。此场景在读的时候,可以正确的读。但是当涉及到写文件,就会存在了一些不可预料的结果。

dup 与 dup2 函数


两个函数都是用来复制一个现有的文件描述符的。有 dup 返回的新文件描述符一定是当前可用文件描述符中的最小值,对于 dup2,可以用fd2参数指定新描述符的值。如果fd2已经打开,则将其关闭先。若fd=fd2,则dup2返回fd2,而不关闭它。

![dup(1) 后的内核数据结构说明

sync、fsync、fdatasync 函数


传统的UNIX系统都会在内核中设有缓冲区告诉缓存或页高速缓存,大多数磁盘IO都是通过缓冲区进行。当向文件写数据时,内核通常会先将数据copy到缓冲区中,然后排入队列,晚些时候会写入到磁盘中,这被称为延迟写。当内核需要重用缓冲区来存放其他睡的时候,会将所有数据写入到磁盘中。为了保证磁盘上实际文件系统与缓冲区中内容的一致性,UNIX系统提供了三种函数,如上。它们有什么区别呢?

fcntl 函数


fcntl 函数可以改变已经打开的文件的属性。

fcntl 的返回值与命令有关。如果出错,所有命令都返回-1;成功会返回其他值。
在修改文件描述符标志或文件状态标志的时候必须谨慎,先要获取现在的标志值,然后再按照期望修改它,最后设置新的标志值。本小节还讲到了调用write时设置同步机制后,对系统性能带来的影响。

ioctl 函数

APUE 学习笔记 —— 文件I/O的更多相关文章

  1. APUE学习笔记-文件I/O

    这次回顾APUE中第三四章的内容,主要是文件I/O操作相关的接口函数.    UNIX系统的文件I/O是不带缓冲的I/O,不带缓冲是指每个read和write都调用系统内核的一个系统调用. 1.文件描 ...

  2. APUE学习笔记3_文件IO

    APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...

  3. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  4. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

  5. [Python学习笔记]文件的读取写入

    文件与文件路径 路径合成 os.path.join() 在Windows上,路径中以倒斜杠作为文件夹之间的分隔符,Linux或OS X中则是正斜杠.如果想要程序正确运行于所有操作系统上,就必须要处理这 ...

  6. APUE学习笔记(2):lseek()练习与文件洞

    对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...

  7. apue学习笔记(第三章 文件I/O)

    本章开始讨论UNIX系统,先说明可用的文件I/O函数---打开文件.读写文件等 UNIX系统中的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close open函数 ...

  8. apue学习笔记(第四章 文件和目录)

    本章将描述文件系统的其他特性和文件的性质. 函数stat.fstat.fstatat和lstat #include <sys/stat.h> int stat(const char *re ...

  9. APUE学习笔记3——文件和目录

    1 简介 之前学习了执行I/O操作的基本函数,主要是围绕普通文件I/O的打开.读或写.下面继续学习Unix文件系统的其他特征和文件的基本性质.我们将从stat函数开始,了解stat结构所代表的文件属性 ...

随机推荐

  1. label标签的可访问性问题

    label标签可以优雅地扩大表单控件元素的点击区域.例如,单纯的单选框点击区域就鼻屎那么大的地方,经常会点不到位置.因此,label标签的使用对于提高页面的可用性可访问性是很有帮助的. 其实,它的样子 ...

  2. 51nod 1021 石子归并 (动态规划 简单代码)

    题目: 思路:动态规划,递推式子 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]);     dp[i][j]表示 ...

  3. jQuery学习(五)——使用JQ完成复选框的全选和全不选

    1.在系统后台进行人员管理时,进行批量删除,使用jq完成全选和全不选 步骤分析: 第一步:引入jquery文件 第二步:书写页面加载函数 第三步:为上面的复选框绑定单击事件 第四步:将下面所有的复选框 ...

  4. HTML基础——网站友情链接显示页面

    1.列表标签 有序列表:type默认是1,2,3……,reserved指降序排列 <ol type="I" start="" reversed=" ...

  5. 简单暴力的TP5多主题方案

    一个小项目,需要配置多套前端主题.解决的思路是根据域名加载不同的主题配置. 一.在应用目录 application 下创建 common 目录. 二.application/common 目录下创建 ...

  6. [HNOI2015]亚瑟王(期望+DP)

    题解 利用期望的线性性,可以把问题转化为求每一个卡牌造成期望的期望值. 然后我们就需要知道每一个卡牌发动技能的概率. 因为当某一张卡牌发动技能时这一轮会结束,这就很难直接计算了. 我们使用DP 设dp ...

  7. 基础命令:chown

    chown:改变文件或目录的用户和用户组 [语法格式] chown [option] [OWNER][:[GROUP]] [file] chown  [选项]  [用户 : 用户组 ]  [<文 ...

  8. pandas 5 导入导出 读取保存 I/O API

    官网The pandas I/O API pickle格式是python自带的 from __future__ import print_function import pandas as pd da ...

  9. 紫书 习题8-8 UVa 1612 (贪心+精度)

    这道题我很快就写出来了, 但是一直WA, 然后发现是精度, 这坑了我一个小时-- (1)贪心.每次就尽量分数高, 可以保证最后分数最高 (2)神tm精度问题.记住判断大于小于和等于的时候要用EPS(1 ...

  10. POJ——T 1422 Air Raid

    http://poj.org/problem?id=1422 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8579   A ...