APUE 学习笔记 —— 文件I/O
本章节主要讲了 Linux 系统下的关于文件I/O操作的几个函数:open、read、write、lseek、close 的使用和需要注意的一些细节。接着,又介绍了多进程见如何共享文件。下面开始知识点梳理。
文件描述符
对于内核来说,所有打开的文件,都是通过文件描述符来引用。当打开或创建一个新的文件的时候,内核都会向进程返回该文件的文件描述符。文件描述符是什么,可以参考维基百科——文件描述符。UNIX 系统按惯例,会将0与进程的标准输入关联,将1与进程的标准输出关联,将2与进程的标准错误关联。
open 与 openat 函数的使用

oflag参数:
是通过在头文件 <fcntl.h> 中定义的常量中的一个或多个进行 “或”运算构成的。这里不再一一详述每个常量及其含义,感兴趣的小伙伴可以自行去查阅。path参数:
是要打开和创建文件的名字。fd参数:
fd 把open 和 openat 函数区分开来,具体有三种可能:- 当path是绝对路径时, openat 就相当于是 open;
- path制定的是相对路径名称时,fd指出了相对路径名称的在文件系统中的开始位置;
- 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,而不关闭它。


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

fcntl 函数

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

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

APUE 学习笔记 —— 文件I/O的更多相关文章
- APUE学习笔记-文件I/O
这次回顾APUE中第三四章的内容,主要是文件I/O操作相关的接口函数. UNIX系统的文件I/O是不带缓冲的I/O,不带缓冲是指每个read和write都调用系统内核的一个系统调用. 1.文件描 ...
- APUE学习笔记3_文件IO
APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...
- APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause
转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...
- 《python基础教程(第二版)》学习笔记 文件和素材(第11章)
<python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...
- [Python学习笔记]文件的读取写入
文件与文件路径 路径合成 os.path.join() 在Windows上,路径中以倒斜杠作为文件夹之间的分隔符,Linux或OS X中则是正斜杠.如果想要程序正确运行于所有操作系统上,就必须要处理这 ...
- APUE学习笔记(2):lseek()练习与文件洞
对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...
- apue学习笔记(第三章 文件I/O)
本章开始讨论UNIX系统,先说明可用的文件I/O函数---打开文件.读写文件等 UNIX系统中的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close open函数 ...
- apue学习笔记(第四章 文件和目录)
本章将描述文件系统的其他特性和文件的性质. 函数stat.fstat.fstatat和lstat #include <sys/stat.h> int stat(const char *re ...
- APUE学习笔记3——文件和目录
1 简介 之前学习了执行I/O操作的基本函数,主要是围绕普通文件I/O的打开.读或写.下面继续学习Unix文件系统的其他特征和文件的基本性质.我们将从stat函数开始,了解stat结构所代表的文件属性 ...
随机推荐
- jq弹窗(获取页面宽高,滚轮高度,始终居中)
jq写一个弹窗,效果如上图所示, 点击按钮弹窗弹出,右上角关闭. 弹窗始终显示在页面中间,无论放大缩小窗口,滚轮滚动. 代码如下: html: <br><br><br&g ...
- POJ 3694 Network(Tarjan求割边+LCA)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10969 Accepted: 4096 Descript ...
- word2tex之类的问题
首先就是这个word2tex一般是在word和tex文本互相转换的时候用的. 以前win7下用的chikrii忘了使用方法.. 之后再win10下用的excel2tex,但是转换时候总感觉不如word ...
- sharding-jdbc,轻量级数据库分库分表中间件
Sharding-JDBC是当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架,实现透明化数据库分库分表访问.Sharding-JDBC是继dubbox和ela ...
- 好久不见我又回来了cnblogs
最近一直没时间写博客.... 最近工作中遇到的问题,当时花费了一定功夫才解决. 当再次遇到,同样问题的时候,我知道自己能够解决的,但是却同样,要走原来的弯路解决他. 说到底还时确实总结啊.大概是没时间 ...
- vuecli的使用之项目中的文件
cli创建的项目截图 node_moudule :下载的依赖包的存储位置. public :html的地方??? src :写代码的地方 man.js :入口文件 .browserslistrc :浏 ...
- CSS3中的transition
W3C标准中对CSS3的transition是这样描述的: CSS的transition允许CSS的属性值在一定的时间区间内平滑地过渡.这种效果可以在鼠标单击,获得焦点,被点击或对元素任何改变中触发, ...
- 多任务-进程之Queue的进程间通信
1.经过线程和进程的对比,不难的知道,线程和进程有相当大的区别,如全局变量资源不能够共享. 2.在不同的进程间,如何实现通信呢? 需要提及的一个概念就是Queue,它是一个消息队列,下面通过一个例子来 ...
- CSDN 轻松周赛赛题:能否被8整除
轻松周赛赛题:能否被8整除 题目详情 给定一个非负整数,问能否重排它的全部数字,使得重排后的数能被8整除. 输入格式: 多组数据,每组数据是一个非负整数.非负整数的位数不超过10000位. 输出格式 ...
- Qt之QCryptographicHash
简述 QCryptographicHash类提供了生成密码散列的方法.该类可以用于生成二进制或文本数据的加密散列值.目前支持MD4.MD5.SHA-1.SHA-224.SHA-256.SHA-384和 ...