文件IO

2016-01-29

文件IO

大多数文件io只需要用到5个函数 open read write lseek close。不带缓存的io:每个read和write都调用内核中的一个系统调用。这些函数不是ansi c的组成部分但是是POSIX和xpg3的组成部分。

文件描述符

对于内核而言,所有打开文件都由文件描述符引用。为一个非负整数。按照惯例,unix shell使用文件描述符0与进程的标准输入结合,1与标准输出相结合,文件描述2与标准出错输出相结合。
在POSIX应用中幻数0 1 2 分别被STDIN_FILENO STDOUT_FILENO STDERR_FILENO来代替

open函数

int open(const char *pathname, int oflag, ...)
当且仅当创建新文件时才使用第三个函数。oflag 可以使用 O_RDONLY O_WRONLY O_RDWR(读写) O_APPEND O_CREATE(若文件不存在则创建,需同时说明第三个参数) O_EXCL(如果同时指定了O_CREATE而且文件已经存在,则出错)
O_TRUNC(如果此文件存在而且为只读或者只写成功打开,则将其长度截短为0) O_NOCITY(如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端) O_NONBLOCK(如果pathname指的是一个FIFO、一个块特殊文件或者一个字符特殊文件,则此选项为此文件的本次打开操作和后续的io操作设置非阻塞方式) O_SYNC使每次write都等到物理io操作完成。

create函数

也可以使用create函数创建一个新文件
int create(const char *pathname, mode_t mode); 此函数等价为 open(pathname,O_WRONLY|O_CREATE|O_TRUNC,mode)

close函数

可以使用close函数关闭一个打开的文件,关闭一个文件时也是放该进程加载该文件上的所有记录锁
当一个进程终止时,它所有的打开文件都由内核自动关闭。

lseek函数

每个打开文件都有一个与其相关联的当前文件位移量,它是一个非负整数,用以度量从文件开始处计算的字节数。通常读写操作都从当前文件位移量处开始,并使用位移量增加所读或者所写的字节数。按系统默认,当打开一个文件时,除非指定0_APPEND否则改位移量为0
off_t lseek(int filedesm off_t offset, int whence);
offset的解释与参数whence的值有关
若whence是SEEK_SET则指定位置,SEEK_CUR指定相对位置,SEEK_END文件长度加上offset
如果文件描述符引用的是一个管道或者FIFO则seek返回-1并将errno设置为EPIPE
通常,文件当前位移量是非负整数,但是某些设备可能允许负的位移量,所以在比较lseek的返回值时不要测试它是否小于零而要测试其是否等于-1。seek 的大小可以超过文件的长度,这样下一次写入操作会延长该文件

read函数

用read函数从打开文件中读取数据
ssize_t read(int filedes, void *buff, size_t nbytes) 返回读到的字节数,若已到文件尾为0,出错返回-1
读位移量增加实际读的字节数
有许多情况实际督导的字节数少于要求读字节数

  • 读普通文件时,在读到要求字节数之前已经到达了文件尾端
  • 从网络读时,网络中的缓冲机构可能造成返回值小于所要求的读字节数
  • 某些面向记录的设备,如磁带,一次最多返回一个记录

write函数

用write函数向打开的文件写数据
ssize_t write(int filedes, const void * buff, size_t nbytes) 若成功返回已写的字节数,若出错为-1
write出错的一个常见原因是磁盘已写满,或者操过了对一个给定进程的文件长度限制

io效率

对于unix内核而言文本文件和二进制文件并无区别
测试一个1428802的文件读写 buffer设置8192时其读写效率比较高

文件共享

unix支持在不同进程间共享打开文件
1、每个进程在进程表中都有一个记录项,每个记录项中有一张打开文件描述符表,可以将其视为一个矢量,每个描述符占用一项
与文件描述符相关联的是 文件描述符标识 指向一个文件表的指针
2、内核会为所有打开文件维持一张文件表,每个文件表项包含 文件状态标识 当前文件位移量 指向该文件v节点表项的指针
3、每个打开文件(或设备)都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。v节点还包含了该文件的i节点。这些信息是在打开文件时从盘上读入内存的。i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件在盘上所使用的实际数据块的指针等等。
当多个进程打开同一个文件时每个进程都单独对应一个文件表,而他们的v节点指针指向同一个v节点
当多个进程写同一个文件时,则可能产生逾期不到的结果

原子操作

任何一个要求多余1个函数调用的操作都不能成为原子操作,因为在两个函数调用之间,内核有可能会临时挂起该进程
unix提供了一种方法使这种操作成为原子操作,其方法就是在打开文件时设置O_APPEND标识。这就使得内核每次对这种文件进行写之前都将进程的当前位移量设置到文件的尾端,于是在每次写之前就不再需要调用lseek。

创建一个文件

在对open函数中O_CREAT和O_EXCL将文件的创建作为一个原子操作
int dup(int filedes) 和 int dup2(int filedes, int filedes2) 复制一个现存的文件描述符
dup返回新文件描述符一定是当前可用的文件描述符中的最小值。用dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则现将其关闭。若filedes等于filedes2 则dup2返回filedes2而不关闭它。这些函数返回的新文件描述符与参数filedes共享同一个文件表项。

fcntl

fcntl函数可以改变已经打开文件的性质
int fcntl(int filedes, int cmd, ....);
fcntl函数有五种功能:

  • 复制一个现存的描述符(cmd = F_DUPFD)
  • 获得/设置文件描述符标记(cmd = F_GETFD|F_SETFD)
  • 获得或设置文件状态标识(cmd = F_GETFL|F_SETFL)
  • 获得或设置异步io所有权(cmd=F_GETOWN|F_SETOWN)
  • 获得或设置记录锁 (cmd = F_GETLK,F_SETLK,F_SETLKW)
    F_DUPFD复制文件描述符,新文件描述符作为函数值返回。它是尚未打开的个描述符中大于或等于第三个参数值中各值的最小值。
    F_GETFL 对应于filedes的文件状态标识作为函数值返回,文件状态如O_RDONLY O_WRONLY ...
    F_SETFL设置文件状态 可更改为 O_APPEND O_NONBLOCK O_SYNC O_ASYNC
    F_GETOWN 取当前接受SIGIO和SIGURG信号的进程ID或进程组ID
    fnntl 的返回值与命令有关,如果出错统一返回-1
    在unix中通常write只是将数据排入队列,而实际的io操作可能在以后的某个时刻进行。
    程序运行时设置O_SYNC标识会增加时钟时间

ioctl函数

ioctl函数是io操作的杂物箱。
int ioctl(int filedes, int request, ...)

/dev/fd

打开文件/dev/fd/n等效于复制描述符n
某些系统提供路径名/dev/stdin /dev/stdout /dev/stderr 等效于/dev/fd/0 ...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数文件描述符标准符号常量文件描述符0标准输...
    秋风潇潇1992阅读 288评论 0 0
  • 本文主要介绍了如下内容: C标准库函数与系统函数的关系 进程控制块 文件描述符 系统调用:open、close、r...
    echoworlding阅读 810评论 2 2
  • 开始本章学习之前了解一些概念: 1、带缓存和不带缓存IO 参考系统调用,用户程序通过系统级别API调用系统函数将请...
    lifesmily阅读 409评论 0 0
  • 一、文件IO涉及哪些接口?(内核向用户空间提供了哪些接口?) Input ,Output:是从用户空间角度考虑的输...
    3e1094b2ef7b阅读 550评论 0 0
  • 文件IO Unix系统中的文件I/O通常只用到5个函数:open、read、write、lseek和close。这...
    大雄good阅读 777评论 0 0