这次回顾APUE中第三四章的内容,主要是文件I/O操作相关的接口函数。

    UNIX系统的文件I/O是不带缓冲的I/O,不带缓冲是指每个read和write都调用系统内核的一个系统调用。

1.文件描述符

  UNIX I/O的所有函数都是基于文件描述符来操作的。那什么是文件描述符呢?文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。该文件描述符fd是所有UNIX I/O函数的操作对象。UNIX系统把文件描述符0与进程标准输入关联,把文件描述符1与进程标准输出关联,把文件描述符2与标准错误关联。我们一般在程序中用STDINPUT_FILENO,STDOUTPUT_FILENO,STDERR_FILENO代替这几个文件描述符。文件描述符的范围是0~OPEN_MAX-1。

2.基本I/O函数

#include <fcntl.h>

int open(const char *path,int oflag,.../* mode_t mode */);  /* xx */

int openat(int fd,const char *path,int oflag,.../* mode_t mode */);

【成功返回文件描述符,出错返回-1】

  调用open函数打开一个文件,path是要打开或创建的文件的名字,oflag用来说明该函数的多个选项。对于openat函数,在UNIX这一系列I/O函数中有很多类似openat带at后缀的xxat函数,它们的功能与xx函数类似,只不过是xx函数是用文件的绝对路径名来调用,而xxat函数是用文件描述符加上相对路径名来调用,对xxat类函数来说,当path参数指向一个绝对路径名时,其参数fd也失效,此时xxat函数与xx函数相同。(再后面对于这种函数我会用xx注释说明,就不再列出xxat函数了)。

  open函数的oflag参数是用多个系统定义的常量做‘或’运算得出。首先是O_RDONLY,O_WRONLY,O_RDWR,O_EXEC,O_SEARCH(这五个常量中必须指定一个且只能指定一个)。剩下的我只列出几个我觉得用的频繁些的:O_APPEND,每次写时都追加到文件末尾;O_CREAT,若此文件不存在则创建,使用该选项时,函数第三个参数mode需指定文件访问权限;O_TRUNC,若文件存在,且是只写或读-写打开,则将文件长度截断为零。

#include <fcntl.h>

int creat(const char *path,mode_t mode);

【成功,返回以WRONLY打开的文件描述符;出错返回-1】

#include <unistd.h>

int close(int fd);【成功,返回0;出错返回-1】

注:当一个进程终止时,内核会自动关闭它打开的所有文件,因此很多程序都利用这一点不显式调用close关闭。

off_t lseek(int fd,off_t offset,int whence);【成功,返回文件新的偏移量;失败返回-1】

whence有三种值:SEEK_SET,此时文件偏移量设置为据文件开始初offset个字节处;SEEK_CUR,此时将文件偏移量设置为其当前值加offset;SEEK_END,此时文件偏移量设置为文件长度加offset。

ssize_t read(int fd,void *buf,size_t nbytes);【成功,返回读到字节数,若已到文件尾,返回零;出错返回-1】

从文件描述符所指文件读n字节到buf数组。ssize_t是带符号返回值int,size_t是unsigned int

ssize_t write(int fd,void *buf,size_t nbytes);【成功,返回已写字节数;出错返回-1】

从buf数组读n字节写入fd所指文件。对普通文件,写操作从文件当前偏移量出开始;对于文件打开时指定了O_APPEND位,每次写操作是在文件末尾。

3.文件共享

  UNIX支持在不同进程间共享打开文件。UNIX内核表示打开文件的数据结构如下所示(手机拍的凑合着看):

a.每个进程在进程表中都有一个记录项,记录项包含一张打开文件的文件描述符表,表中每一项关联文件描述符标志及一个指向文件表项的指针。

b.内核为所有打开文件维持一张文件表,每个表项包含文件状态标志,当前文件偏移量,v节点指针。

c.每个打开文件都有一个v节点结构。v节点包含了文件类型和对文件进行各种操作的函数指针。还包含了文件的i节点,i节点包含了文件的所有者,文件长度,指向文件实际数据块在磁盘上的指针等信息。

  两独立进程各自打开同一文件的示意图:

#include <unistd.h>

int dup(int fd);【成功,返回新文件描述符,出错返回-1】

复制现有文件描述符,返回的文件描述符是当前可用的文件描述符中最小的那个。

int fsync(int fd);

int fdatasync(int fd);

【成功,返回0,出错返回-1】

void sync(void);

sync只是将所修改的块缓冲区加入写队列,然后就返回,不等待写磁盘操作解数。

fsync只对文件描述符fd指定的文件有用,且要等写磁盘操作完成才返回。

fdatasync类似于fsync,只是fdatasync只影响文件数据部分。

#include <fcntl.h>

int fcntl(int fd,int cmd,.../* arg */);

该函数用于改变已打开文件的属性。fcntl的功能与cmd有关。

To be continued...

APUE学习笔记-文件I/O的更多相关文章

  1. APUE 学习笔记 —— 文件I/O

    本章节主要讲了 Linux 系统下的关于文件I/O操作的几个函数:open.read.write.lseek.close 的使用和需要注意的一些细节.接着,又介绍了多进程见如何共享文件.下面开始知识点 ...

  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. Yii Listview 更新及搜索

    更新: http://my.oschina.net/shixiaobao17145/blog/130992 http://www.yiiframework.com/forum/index.php/to ...

  2. PC-信使服务之不用聊天软件也能通信

    net send 192.168.1.2 OK 二台电脑都要开启messenger服务.

  3. [置顶] 漫谈SOA(面向服务架构)

    面向服务架构的思想在整个软件的架构中已经不是什么新鲜的东西.我简单的认为服务化是模块化的延伸,所以服务化有着和模块化类似的优点和缺点.这里不再讨论这些服务定义服务与服务之间的通信协议(像WSDL等等) ...

  4. Java 中 String 类和StringBuilder 类的常用方法

    String 类提供了许多用来处理字符串的方法,例如,获取字符串长度.对字符串进行截取.将字符串转换为大写或小写.字符串分割等,下面我们就来领略它的强大之处吧. String 类的常用方法: 结合代码 ...

  5. myeclipse中使用gradle开发项目

    gradle可以直接使用maven的代码库,并且支持编程,可以说是maven的加强版.今天我们学习下,如何在MyEclipse下使用gradle开发项目.我们的开发环境:myeclipse 2015, ...

  6. 利用dom4j读取xml文件

    对于xml文件的读取,其实有很多方法,例如:SAX实现方法,DOM4J实现方法 ,DOM 实现方法,JDOM实现方法 等等. 下面,我就说下dom4j的读取方法: 1.首先,肯定要引入第三方jar包. ...

  7. iOS设计模式之生成器

    iOS设计模式之生成器 1.生成器模式的定义 (1): 将一个复杂的对象的构件与它的表示分离,使得相同的构建过程能够创建不同的表示 (2): 生成器模式除了客户之外还包括一个Director(指导者) ...

  8. linux下启动某个进程

    在关闭窗口的情况下,能够在后台继续运行,如 启动命令 node /home/node_modules/pixel-ping/lib/pixel-ping.js /home/node_modules/p ...

  9. Hdu 2473(并查集删除操作) Junk-Mail Filter

    有木有非常吊 加强 加强版   啊  ,看了都不敢做了   .后来先做了食物链这个我还是看过的.但还是A不掉,没明确神魔意思 .总而言之.大牛的博客是个好东西.我就那么看了一下,还是不懂怎莫办啊,哎, ...

  10. oracle学习----DDL锁理解

    DDL锁分为三种 1.排他DDL锁 2.共享DDL锁 3.可中断解析锁 大部分DDL都带有排他DDL锁,如一个表被修改中,可以使用select查询数据,但是大多数操作都是不允许执行的,包括所有其他DD ...