本章节主要讲了 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. IDEA模板设置

    /**   * @className: $CLASSNAME$   * @author: liuyachao   * @date: $DATE$ $TIME$ */ ================= ...

  2. 电信流氓注入JS

    (function () { var cs_url = _pushshowjs_.url, cs_delay = window.cs_delay; var cs_styles = window.sty ...

  3. Springboot如何利用http请求控制器

    写好了接口,现在想用postman测试一下这个接口是否正确,想请问怎么传入请求参数?先谢谢了! Springboot如何利用http请求控制器 >> java这个答案描述的挺清楚的:htt ...

  4. select标签下option标签里value属性有什么用以及和text的区别

    转自:http://blog.csdn.net/summer_sy/article/details/54572398 1:value的用处 <select > <option val ...

  5. 转js调优

    随着网络的发展,网速和机器速度的提高,越来越多的网站用到了丰富客户端技术.而现在Ajax则是最为流行的一种方式.javascript是一种解释型 语言,所以能无法达到和C/Java之类的水平,限制了它 ...

  6. 【原创】java中各种集合类的实现浅析

    [LinkedList] LinkedList使用了链表来实现List功能,而且是双向循环链表,它的Entry定义如下: private static class Entry<E> { / ...

  7. CSS3新增的属性有哪些:

    CSS 用于控制网页的样式和布局. CSS3 是最新的 CSS 标准. CSS3新增了很多的属性,下面一起来分析一下新增的一些属性: 1.CSS3边框: border-radius:CSS3圆角边框. ...

  8. 前端换行显示,后端返回<br>

  9. HTML提交表单

    一.使用form提交表单 <form action="#" method="post"> {% csrf_token %} 班级<input ...

  10. 【BZOJ3678】Wangxz和OJ

    题意: 不想讲 题解: Rope真香! 正解是Splay缩点,访问时再拆成一个序列 代码: //STL dafa good! #include<algorithm> #include< ...