PILE读书笔记_文件I/O
open函数
int open(const char *pathname, int flags, mode_t mode);
参数说明:
(1)pathname: 表示要打开的文件路径
(2)flags: 用于指示打开文件的选项,常用的有O_RDONLY、 O_WRONLY和O_RDWR,还有一些选项如下:
- O_APPEND: 每次进行写操作时, 内核都会先定位到文件尾, 再执行写操作
- O_ASYNC: 使用异步I/O模式
- O_CLOEXEC: 在打开文件的时候, 就为文件描述符设置FD_CLOEXEC标志。 这是一个新的选项, 用于解决在多线程下fork与用fcntl设置FD_CLOEXEC的竞争问题。 某些应用使用fork来执行第三方的业务, 为了避免泄露已打开文件的内容, 那些文件会设置FD_CLOEXEC标志。 但是fork与fcntl是两次调用, 在多线程下, 可能会在fcntl调用前, 就已经fork出子进程了, 从而导致该文件句柄暴露给子进程
- O_CREAT: 当文件不存在时, 就创建文件
- O_DIRECT: 对该文件进行直接I/O, 不使用VFS Cache
- O_DIRECTORY: 要求打开的路径必须是目录
- O_EXCL: 该标志用于确保是此次调用创建的文件, 需要与O_CREAT同时使用; 当文件已经存在时, open函数会返回失败
- O_LARGEFILE: 表明文件为大文件
- O_NOATIME: 读取文件时, 不更新文件最后的访问时间
- O_NONBLOCK、 O_NDELAY: 将该文件描述符设置为非阻塞的( 默认都是阻塞的)
- O_SYNC: 设置为I/O同步模式, 每次进行写操作时都会将数据同步到磁盘, 然后write才能返回
- O_TRUNC: 在打开文件的时候, 将文件长度截断为0, 需要与O_RDWR或O_WRONLY同时使用。在写文件时, 如果是作为新文件重新写入, 一定要使用O_TRUNC标志, 否则可能会造成旧内容依然存在于文件中的错误
(3)mode: 只在创建文件时需要, 用于指定所创建文件的权限位( 还要受到umask环境变量的影响)
lseek函数
off_t lseek(int fd, off_t offset, int whence);
该函数用于将fd的文件偏移量设置为以whence为起点, 偏移为offset的位置。 其中whence可以为三个值: SEEK_SET、 SEEK_CUR和SEEK_END, 分别表示为“文件的起始位置”、 “文件的当前位置”和“文件的末尾”, 而offset的取值正负均可。 lseek执行成功后, 会返回新的文件偏移量。文件偏移是基于某个打开文件来说的, 一般情况下, 读写操作都会从当前的偏移位置开始读写( 所以read和write都没有显式地传入偏移量) , 并且在读写结束后更新偏移量。
返回值:当lseek执行成功时, 它会返回最终以文件起始位置为起点的偏移位置。 如果出错,则返回-1, 同时errno被设置为对应的错误值。也就是说, 一般情况下, 对于普通文件来说, lseek都是返回非负的整数, 但是对于某些设备文件来说, 是允许返回负的偏移量。 因此要想判断lseek是否真正出错, 必须在调用lseek前将errno重置为0,然后再调用lseek, 同时检查返回值是否为-1及errno的值。 只有当两个同时成立时, 才表明lseek真正出错了。
read函数
ssize_t read(int fd, void *buf, size_t count);
read尝试从fd中读取count个字节到buf中, 并返回成功读取的字节数, 同时将文件偏移向前移动相同的字节数。 返回0的时候则表示已经到了“文件尾”。 read还有可能读取比count小的字节数。
使用read进行数据读取时, 要注意正确地处理错误, 也是说read返回-1时, 如果errno为EAGAIN、EWOULDBLOCK或EINTR, 一般情况下都不能将其视为错误。 因为前两者是由于当前fd为非阻塞且没有可读数据时返回的, 后者是由于read被信号中断所造成的。 这两种情况基本上都可以视为正常情况。
write函数
ssize_t write(int fd, const void *buf, size_t count);
write尝试从buf指向的地址, 写入count个字节到文件描述符fd中, 并返回成功写入的字节数, 同时将文件偏移向前移动相同的字节数。 write有可能写入比指定count少的字节数。
dup函数
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int dup3(int oldfd, int newfd, int flags);
(1)dup:使用一个最小的未用文件描述符作为复制后的文件描述符。
(2)dup2:使用用户指定的文件描述符newfd来复制oldfd的。 如果newfd已经是打开的文件描述符, Linux会先关闭newfd, 然后再复制oldfd。
(3)dup3:只有定义了feature宏“_GNU_SOURCE”才可以使用, 它比dup2多了一个参数, 可以指定标志——不过目前仅仅支持O_CLOEXEC标志, 可在newfd上设置O_CLOEXEC标志。 定义dup3的原因与open类似, 可以在进行dup操作的同时原子地将fd设置为O_CLOEXEC, 从而避免将文件内容暴露给子进程。
在写daemon服务程序时, 基本上都有这样的流程: 首先关闭标准输出stdout、 标准出错stderr, 然后进行dup操作, 将stdout或stderr重定向。 但是在多线程程序成为主流以后,由于close和dup操作不是原子的, 这就造成了在某些情况下, 重定向会失败。 因此就引入了dup2将close和dup合为一个系统调用, 以保证原子性, 然而这依然有问题。 大家可以回顾1.2.2节中对O_CLOEXEC的介绍。 在多线程中进行fork操作时, dup2同样会有让相同的文件描述符暴露的风险, dup3也就随之诞生了。 这三个系统调用看起来有些冗余重复, 但实际上它们也是软件工程发展的结果。
sync函数
void sync(void);
int fsync(int fd);
int fdatasync(int fd);
(1)Linux的sync是阻塞调用 ,并不是说让所有修改过的缓存进入提交队列, 并不用等待这个工作完成,这一点和APUE上面是不同的,以这个结论为准
(2)fsync只同步fd指定的文件, 并且直到同步完成才返回,它不仅同步数据, 还会同步所有被修改过的文件元数据(包括文件的访问权限、 上次访问的时间戳、 所有者、 所有组、 文件大小等信息)
(3)fdatasync与fsync类似, 但是其只同步文件的实际数据内容, 不会影响后面数据操作的元数据
sync、 fsync和fdatasync只能保证Linux内核对文件的缓冲被冲刷了, 并不能保证数据被真正写到磁盘上, 因为磁盘也有自己的缓存。
stat函数
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
(1)stat得到路径path所指定的文件基本信息
(2)fstat得到文件描述符fd指定文件的基本信息
(3)lstat与stat则基本相同, 只有当path是一个链接文件时, lstat得到的是链接文件自己本身的基本信息而不是其指向文件的信息
truncate 函数
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
(1)truncate截断的是路径path指定的文件
(2)ftruncate截断的是fd引用的文件
“截断”给人的感觉是将文件变短, 即将文件大小缩短至length长度。 实际上, length可以大于文件本身的大小, 这时文件长度将变为length的大小, 扩充的内容均被填充为0。 需要注意的是, 尽管ftruncate使用的是文件描述符, 但是其并不会更新当前文件的偏移。
PILE读书笔记_文件I/O的更多相关文章
- PILE读书笔记_进程环境
进程是操作系统运行程序的一个实例, 也是操作系统分配资源的单位. 在Linux环境中, 每个进程都有独立的进程空间, 以便对不同的进程进行隔离, 使之不会互相影响. atexit函数 #include ...
- PILE读书笔记_标准I/O
在学习和分析标准I/O库的同时, 可以重点与Linux的I/O系统调用进行比较. stdin. stdout和stderr都是FILE类型的文件指针, 是由C库静态定义的, 直接与文件描述符0. 1和 ...
- PILE读书笔记_基础知识
程序的构成 Linux下二进制可执行程序的格式一般为ELF格式. 我们可以用readelf命令来读取二进制的信息. ELF文件的主要内容就是由各个section及symbol表组成的. 下面来分别介绍 ...
- 『TensorFlow』读书笔记_进阶卷积神经网络_分类cifar10_下
数据读取部分实现 文中采用了tensorflow的从文件直接读取数据的方式,逻辑流程如下, 实现如下, # Author : Hellcat # Time : 2017/12/9 import os ...
- The Way to Go读书笔记_第4章_基本结构和基本数据类型
“_”标识符 _ 本身就是一个特殊的标识符,被称为空白标识符.它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用 ...
- Node.js高级编程读书笔记 - 2 文件和进程处理
Outline 3 文件.进程.流和网络 3.1 查询和读写文件 3.2 创建和控制外部进程 3.3 读写数据流 3 文件.进程.流和网络 3.1 查询和读写文件 path 从Node 0.8起,pa ...
- linux笔记_文件搜索命令
一.locate命令 locate命令属于mlocate包,如果执行locate filename提示命令未找到执行安装mlocate包 # yum -y install mlocate 安装后执行l ...
- 『TensorFlow』读书笔记_进阶卷积神经网络_分类cifar10_上
完整项目见:Github 完整项目中最终使用了ResNet进行分类,而卷积版本较本篇中结构为了提升训练效果也略有改动 本节主要介绍进阶的卷积神经网络设计相关,数据读入以及增强在下一节再与介绍 网络相关 ...
- Java精选笔记_文件上传与下载
文件上传与下载 如何实现文件上传 在Web应用中,由于大多数文件的上传都是通过表单的形式提交给服务器的,因此,要想在程序中实现文件上传的功能,首先得创建一个用于提交上传文件的表单页面. 为了使Serv ...
随机推荐
- 在Strust2 使用datatimepicker 标签引发的一系列问题
问题:出现无法识别的问题 原因:Strust2.1开始,对于ajax类的标签不再使用<%@ taglib prefix="s" uri="/struts-tags& ...
- [BZOJ 1143] 祭祀river
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1143 Solution: 一道最长反链的模板题 由Dilworth定理可知:最小链覆盖数 ...
- 【计算几何】【极角序】【二分】bzoj1914 [Usaco2010 OPen]Triangle Counting 数三角形
极角排序后枚举每个点,计算其与原点连线的左侧的半平面内的点与其组成的三角形数(二分/尺取),这些都不是黄金三角形. 补集转化,用平面内所有三角形的个数(C(n,3))减去这些即可. 精度很宽松,几乎不 ...
- 【博弈论】【SG函数】【枚举】bzoj1874 [BeiJing2009 WinterCamp]取石子游戏
枚举第一步可能达到的状态,判断是否是必败态即可. #include<cstdio> #include<set> #include<cstring> using na ...
- Problem L: 输出200-299之间的所有素数
#include<stdio.h> #include<math.h> int main() { int count,m,n,i; count=; ;m<;m++) { n ...
- android多线程-AsyncTask之工作原理深入解析(上)
关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...
- 利用Teensy进行EM410x卡模拟以及暴力破解EM410X类门禁系统可行性猜想
前些天Open入手了Teensy++2.0模拟EM410X,并且针对EM410X的门禁进行了一次暴力破解测试,以下就是相关代码以及内容. 什么是低频?什么是EM410x? 首先,我不得不再次提一下那些 ...
- Linux中C语言的编程
编译的过程 编译的概念:编译程序读取源程序(字符流),对之进行词法与语法的分析,将高级语言指令转换成功能等效的汇编代码,再由汇编程序转换成机器语言,并且按照操作系统对可执行文件格式的要求链接成可执行程 ...
- javascript快速入门19--定位
元素尺寸 获取元素尺寸可以使用下面几种方式 元素的style属性width,height,但这些属性往往返回空值,因为它们只能返回使用行内style属性定义在元素上的样式 元素的currentStyl ...
- webpack配置:css文件打包、JS压缩打包和HTML文件发布
一.CSS文件打包 1.在src下新建css文件,在css文件下新建index.css文件,输入以下代码 body{ color:red; font-size:20px; } 2.css建立好后,需要 ...