引言

本章主要讲文件IO包括:open、read、write、lseek以及close。这些函数通常被称为不带缓冲的IO,不带缓冲至每个read与write都有内核中的一个系统调用。这些不是ISO C的组成部分,但是是Posix.1与SUS的组成部分

本章介绍的原子操作概念十分重要

还将介绍dup、fcntl、sync、fsync、ioctl等等

文件描述符

  • 所有文件都通过文件描述符引用
  • 文件描述符是一个非负整数
  • 打开或者创建一个新文件,内核进程返回一个文件描述
  • 读写一个文件时,将其作为参数传递给read或write
  • 使用open或creat将会返回文件描述符标识文件

注意:

unix系统shell把文件描述符0与进程的标准输入关联,文件描述符1与标准输出关联,文件描述符2与标准错误关联。posix.1 0、1、2已经标准化,但在"unistd.h"中将其替换为符号常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO,方便阅读,这是各种shell以及很多应用程序使用的惯例,与内核无关,如果不遵循此惯例,许多unix应用程序不能正常工作

文件描述符变化范围时0~OPEN_MAX-1.ubuntu20.04经过测试是1048576.测试代码如下

函数open与openat

#include <fcntl.h>
int open(const char *path,int oflag, .../*mode_t mode*/);
int openat(int fd,const char *path,int oflag, .../*mode_t mode*/);//成功返回文件描述符,失败返回-1
  • …可变参数
  • open而言,仅当创建新文件时才使用最后这个参数
  • 参数path是要打开或创建文件的名字。
  • oflag参数是说明文件是怎样打开或创建

常用如下 O_RDONLY、O_WRONLY、O_RDWR

O_EXEC执行打开

O_EXEC每次写时都追加到尾端

O_CLOEXEC

O_CREAT若此文件不存在则创建,必须指定第三个参数mode,新文件文件权限位,用umask可修改

O_DIRECTORY path必须是目录,否则出错




open与openat在有无文件描述符fd上的区别

  • path参数是绝对路径名,fd不起作用,openat==open
  • path为相对路径名,fd指出相对路径在文件系统中的地址,fd参数通过打开相对路径名所在的目录来获取
  • path为相对路径名,fd参数为AT_FDCWD。路径名在当前工作目录获取,openat与open在操作上类似

openat在posix存在的意义

  • 让线程可以使用相对路径名打开目录中的文件,不再只能打开当前工作目录
  • 避免time-of-check-to-time-of-use,TOCTTOU

文件名和路径名截断

截断顾名思义就是从中间截去一部分,保留前半部分,比如最大文件名长度为14字符,创建了一个15字符的新文件,文件名自动截断为14字符

函数creat

#include "fcntl.h"
int creat(const char *path,mode_t mode);//成功返回文件描述符,失败返回-1

此函数相当于open(path,O_WRONLY|O_CREAT|O_TRUNC,mode);只能易写的方式创建,如果创建并返回可读写的文件描述符open(path,O_RDWR|O_CREAT|O_TRUNC,mode);更好

函数close

#include <unistd.h>
int close(int fd); //成功返回0,否则返回-1

关闭一个文件,释放该进程加在该文件上所有记录锁

函数lseek

每个打开文件都有一个文件偏移量

文件偏移量

  • 一般为非负整数,也可能出现负
  • 用以度量从文件开始处计算的字节数
  • 读写操作都从文件偏移量处开始,并使偏移量增加所读写的字节数
  • 默认打开一个文件偏移量为0,从头开始读写,除非打开时有O_APPEND参数
  • 被记录在内核,不引起IO操作,用于下一次读写
  • 文件偏移量可以大于文件当前长度,这种情况对该文件下次写将加长该文件,中间形成空洞,位于文件中没被写过的字节都为0,并且不需要重新分配磁盘块
#include "unistd.h"
off_t lseek(int fd,off_t offset,int whence) //成功返回新的文件偏移量,否则-1
  • whence为SEEK_SET ,将文件偏移量设置为距离文件开始处offset个字节
  • whence为SEEK_CUR,将文件偏移量设置为当前值加上offset个字节,offset可正负
  • whence为SEEK_END ,将文件偏移量设置为文件长度加offset个字节,offset可正负

注意:文件描述符指向管道,FIFO或网络套接字,lseek返回-1,errno设置为ESPIPE

函数read

  • 使用read从打开文件中读取数据,读取nbytes个字节
#include "unistd.h"
ssize_t read(int fd,void *buf,size_t nbytes);//成功返回读到的字节数,出错返回-1
  • 普通文件,读到多少返回多少。

  • 从终端读时一次最多一行

  • 从网络读,缓冲机制可能返回值会小于所要求的字节数

  • 从管道或者FIFO读,返回实际读到的

  • 当一个信号造成中断,读取部分的数据量时

读操作从文件的当前偏移量处开始,在成功返回之前,将增加实际读到的字节数

函数write

  • 写数据
#include “unistd.h”
ssize_t write(int fd,const void *buf,size_t nbytes);// 成功返回写入字节数,出错-1

IO效率

缓冲的重要性,预读技术

文件共享

文件可以在不同进程间共享打开文件

内核使用3种数据结构表示打开文件,他们关系决定了一个进程对另一个进程的影响

  • 每个进程在**进程表都有一个记录项,记录项包含一张打开文件描述符表,矢量,每个描述符占用一项,与每个文件描述符相关联的是**

    • 文件描述符标志(close_on_exec)(FD_CLOEXEC)仅仅是一个标志,当你fork了一个子进程,然后在子进程中调用了exec函数时就用到了该标志.意义是:执行exec前是否要关闭这个文件描述符.
    • 指向一个文件表项的指针
  • 内核为所有打开文件维持一张文件表(文件表项)
    • 文件状态标志,读写添写同步非阻塞
    • 当前文件偏移量
    • 指向该文件v节点表项的指针
  • 每个打开文件(或设备)都有一个v节点(v-node)结构。
    • 包含文件类型
    • 对此文件操作的函数指针
    • 包含i节点(参考第四章)

如下图所示

原子操作

原子操作指的是由多步组成的一个操作,如果该操作执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行一个子集

追加操作

O_APPEND标志就是一个,每次写之前都会定位到尾部,然后写

pread与pwrite

用open创建文件时,o_creat与o_excl搭配也是一个原子操作

函数dup与dup2

复制文件描述符

#include <unistd.h>
int dup(int fd);
int dup2(int fd,int fd2); //成功返回新的文件描述符,出错返回-1
  • dup返回当前可用文件描述符的最小值
  • dup2若fd2已经打开则关闭,若fd==fd2,不关闭它,否则,fd2的FD_CLOEXEC就会清除,fd2在调用exec函数时是打开状态

  • dup2是原子操作

  • dup2与fcntl有不同的errno

sync,fsync和fdatasync

#include <unistd.h>
int fsync(int fd);
int fdatasync(int fd);//成功返回0,出错返回-1
void sync(void);

函数fcntl

用来改变已经打开文件的属性

#include <fcntl.h>
int fcntl(int fd,int cmd, .../*int arg*/);
  • 复制一个已有的描述符(cmd=F_DUPFD或F_DUPFD_CLOEXEC)。

  • 获取/设置文件描述符标志(cmd=F_GETFD或F_SETFD)

  • 获取/设置文件状态标志(cmd=F_GETFL或F_SETFL)

  • 获取/设置异步IO所有权(cmd=F_GETOWN或F_SETOWN)

  • 获取/设置记录锁(cmd=F_GETLK、FSETLK或F_SETLKW)

函数ioctl

18-19章

参考:

《APUE》

文件描述符与文件描述符标志

文件描述符,文件描述符标志,文件状态标志 三个的区别和联系

Linux系统学习笔记:文件描述符标志_

文件描述符标志、文件状态标志_

APUE(第三章)文件IO相关推荐

  1. 第三章 文件IO复习

          open(const char * path, int flag.../*mode_t*/) #include <fcntl.h> path:绝对路径 flag:O_RDONL ...

  2. geopandas学习(三) 文件IO

    geopandas学习(三) 文件IO 文章参考:参考 1.矢量文件的读入 geopandas将fiona作为操纵矢量数据读写功能的后端. 使用geopandas.read_file()读取对应类型文 ...

  3. APUE(第五章)标准IO

    本章介绍的标准IO库,不仅是UNIX,多其他操作系统都实现了标准io库,比如windows,由ISO C标准说明 缓冲的重要性 流和FILE对象 标准IO库的操作是围绕流(stream)进行的. 标准 ...

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

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

  5. APUE(第四章)文件和目录

    重点理解文件系统 函数stat.fstat.fstatat和lstat #include <sys/stat.h> int stat(const char *restrict pathna ...

  6. 第3章 文件IO | 001 文件描述符

    概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非 ...

  7. 第三章 文件过滤及内容编辑处理命令

    3.1 cat cat命令作用: 1.查看文件内容 2.把多个文件合并成一个文件 3.编辑文件内容 4.结合>>和<<EOF进行编辑 5.清空文件内容 -n参数 从1开始对所有 ...

  8. UNIX高级环境编程 第3章 文件IO

    3.3 函数open和openat open int open(const char *pathname, int flags);int open(const char *pathname, int ...

  9. L24.linux命令每日一练 -- 第三章 文件过滤及内容编辑处理命令 -- diff和vimdiff命令

    3.17 diff:比较两个文件的不同 3.17.1 命令详解 ​ [命令星级] ★★★★☆ ​ [功能说明] ​ diff命令可以逐行比较纯文本文件的内容,并输出文件的差异. ​ [语法格式] di ...

最新文章

  1. C# 向TIM或者QQ自动发送中文消息【微信也是可用的】 附测试GIF
  2. SAP UI5关于navigation API的boolean参数
  3. zendstudio 默认网页打开your project的时候不显示本地主机localhost的解决方法
  4. 计算机组成原理写一个运算器,计算机组成原理运算器的实现实验报告.doc
  5. 华为模拟器ensp代码错误2,41,40问题的解决
  6. sourceInsight4 破解笔记(完美破解)【转】
  7. 怎样使用Javascript操作XMLDOM才能兼容IE、FireFox浏览器呢?
  8. LINUX下载编译Which
  9. dos命令之md详解及实例应用
  10. CPU的睿频、超线程、SIMD指令集等特性对密码算法性能的影响
  11. Pytorch实战——知识点记录(一)
  12. 51单片机汇编学习例程(6)——74HC573数码管篇
  13. (附源码课件)10款Java小游戏满足你各种需求
  14. jupyter notebook如何导入excel数据
  15. 一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
  16. 永恒python图片_第1章 python基础
  17. 〖ChatGPT实践指南 - 零基础扫盲篇⑤〗- OpenAI API 演示 Demo 之宠物名字生成器
  18. Centos | 一招解决所有 ImportError: xxx: cannot open shared object file
  19. 家庭用户无线上网案例(AC通过三层口对AP进行管理)
  20. python脚本windows环境下权限问题处理

热门文章

  1. R语言与数据分析(6)-R包的安装
  2. 重磅!中科院白洋研究员加入《宏微名师讲堂》分享高通量分菌技术啦!
  3. TaxonKit:小巧、高效、实用的NCBI分类学数据命令行工具
  4. Science:亚硝酸盐氧化细菌在黑暗海洋中的主要作用
  5. AI科研绘图3:排版
  6. 中国林科院亚热带林业研究所林木根际微生物博士后招聘启事
  7. R语言可视化分面图、假设检验、单变量分组多水平t检验并指定参考水平、可视化单变量分组多水平分面箱图(faceting boxplot)并添加显著性水平、指定显著性参考水平
  8. R语言二项分布函数Binomial Distribution(dbinom, pbinom, qbinom rbinom)实战
  9. python手动将机器学习模型保存为json文件
  10. python实现迭代的快速排序(Iterative Quick Sort)