本章开始讨论UNIX系统,先说明可用的文件I/O函数---打开文件、读写文件等

UNIX系统中的大多数文件I/O只需用到5个函数:open、read、write、lseek以及close

open函数  返回一个最小的未用描述符

#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

其中path参数是打开或创建文件的名字,flags参数由下列一个或多个常量进行“或”运算得到:

O_RDONLY  只读打开

O_WRONLY  只写打开

O_RDWR     读、写打开

O_EXEC  只执行打开

O_SEARCH  只搜索打开(应用于目录)

这5个常量中必须指定一个,下列常量则是可选的:

O_APPEND  每次写时都追加到文件的尾端

O_CLOEXEC  把FD_CLOEXEC常量设置为文件描述符标志

O_CREAT  若此文件不存在则创建它。使用此选项时,open函数必须同时说明第三个参数mode

O_DIRECTORY  如果path引用的不是目录,则出错

O_EXEL  如果同时指定了O_CREAT,而文件已经存在,则出错

O_NOCTTY  如果path引用的是终端设备,则不讲该设备分配作为此进程的控制终端

O_NOFOLLOW  如果path应用的是一个符号链接,则出错

O_NONBLOCK  如果path引用的是一个FIFO、一个块特殊文件或一个字符特殊文件,则设置此文件本次打开操作跟后续的I/O操作为非阻塞方式

O_SYNC  使每次write等待物理I/O操作完成

O_TRUNC  如果此文件存在,而且为只写或读写成功打开,则将其长度截断为0

O_TTY_INIT  如果打开一个还未打开的终端设备,设置非标准termios参数值

creat函数

#include <fcntl.h>
int creat(const char *path,mode_t mode);

该函数相当于open(path,O_WRONLY|O_CREATE|O_TRUNC,mode);

在第四章我们会详细说明文件访问权限,并说明如何指定mode

close函数

#include <unistd.h>
int close(int fd);

close函数用于关闭一个打开文件

lseek函数

#include <unistd.h>
off_t lseek(int fd,off_t offset,int whence);

对参数offset的解释与参数whence的值有关。

若whence是SEEK_SET,则将该文件的偏移量设置为距距文件开始处offset个字节

若whence是SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正或负

若whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可正可负

若lseek成功执行,则返回新的文件偏移量,为此可以用下列方式确定打开文件的当前偏移量

off_t currpos;
currpos=lseek(fd,,SEEK_CUR);

如果文件描述符指向的是一个管道、FIFO、或者网络套接字,则lseek返回-1,并将errno设置为ESPIPE。

read函数

#include <unistd.h>
ssize_t read(int fd,void *buf,size_t nbytes);

如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。

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

write函数

#include <unistd.h>
ssize_t write(int fd,const void *buf,size_t nbytes);

其返回值通常与参数nbytes的值相同,否则表示出错。write出错的一个常见的原因是磁盘已写满,或者超过了一个给定进程的文件长度限制。

对于普通文件,写操作从文件的当前偏移量处开始,如果打开该文件时,指定了O_APPEND选项,则在每次写操作之前,将文件偏移量设置在文件的当前结尾处。

在一次成功写之后,该文件偏移量增加实际写得字节数。

文件共享

进程为打开文件维护3张表

如果两个独立进程各自打开了同一个文件,则有下图所示的关系

函数dup和dup2

#include <unistd.h>
int dup(int fd);
int dup2(int fd,int fd2);

两个函数都可用来复制一个现有的文件描述符

dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。

dup2可以用fd2参数指定新描述符的值。如果fd2已经打开,则先将其关闭。若fd等于fd2,则返回fd2,而不关闭它。

这些函数返回的新文件描述符与参数fd共享一个文件表项,如下图所示:

digit1>&digit2表示要将描述符digit1重定向至描述符digit2的同一文件

理解./a.out > outfile 2>&1与./a.out 2>&1 >outfile的区别

fcnt函数

#include <fcntl.h>
int fcntl(int fd,int cmd,.../* int arg */);

fcntl函数可以改变已经打开文件的属性,它有以下5种功能

1 复制一个已有的描述符(cmd=F_DUPFD或F_DUPFD_CLOEXEC)

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

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

4 获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)

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

我们先说明cmd中的前面8种

F_DUPFD  复制文件描述符fd,返回新的文件描述符。它是尚未打开的各描述符中大于或等于第三个参数值中各值的最小值

F_DUPFD_CLOEXEC  复制文件描述符,设置与新描述符关联的FD_CLOEXEC文件描述符标志的值,返回新的文件描述符

F_GETFD  对应于fd的文件描述符标志做为函数值返回,当前只定义了一个文件描述符标志FD_CLOEXEC

F_SETFD  对于fd设置文件描述符标志。

F_GETFL  对应于fd的文件状态标志作为函数值返回,下图列出fcntl的文件状态标志

其中,3种访问方式标志(O_RDONLY,O_WRONLY,O_RDWR)并不各占一位,因此首先必须用屏蔽字O_ACCMODE取得访问方式位,然后将结果与这3个值得每一个比较。

F_SETFL  将文件状态标志设置为第三个参数的值。可以更改的几个标志是O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC和O_ANSYNC

F_GETTOWN  获取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。

F_SETOWN  设置接收SIGIO和SIGURG信号的进程ID或进程组ID

下面程序将打印文件状态标志说明

#include "apue.h"
#include <fcntl.h> int
main(int argc, char *argv[])
{
int val; if (argc != )
err_quit("usage: a.out <descriptor#>"); if ((val = fcntl(atoi(argv[]), F_GETFL, )) < )
err_sys("fcntl error for fd %d", atoi(argv[])); switch (val & O_ACCMODE) {
case O_RDONLY:
printf("read only");
break; case O_WRONLY:
printf("write only");
break; case O_RDWR:
printf("read write");
break; default:
err_dump("unknown access mode");
} if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf(", nonblocking");
if (val & O_SYNC)
printf(", synchronous writes"); #if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
if (val & O_FSYNC)
printf(", synchronous writes");
#endif putchar('\n');
exit();
}

下面函数用于设置文件状态标志

#include "apue.h"
#include <fcntl.h> void
set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
int val; if ((val = fcntl(fd, F_GETFL, )) < )
err_sys("fcntl F_GETFL error"); val |= flags; /* turn on flags */ if (fcntl(fd, F_SETFL, val) < )
err_sys("fcntl F_SETFL error");
}

apue学习笔记(第三章 文件I/O)的更多相关文章

  1. The Road to learn React书籍学习笔记(第三章)

    The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...

  2. 《DOM Scripting》学习笔记-——第三章 DOM

    <Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...

  3. [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设

    [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...

  4. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

  5. [HeadFirst-JSPServlet学习笔记][第三章:实战MVC]

    第三章 实战MVC J2EE如何集成一切 Java2企业版(Java 2 Enterprise Editon,J2EE)是一种超级规范.规定了servlets2.4,JSP2.0,EJB2.1(Ent ...

  6. python学习笔记——第三章 串

    第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...

  7. c#高级编程第七版 学习笔记 第三章 对象和类型

    第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...

  8. JavaScript高级编程学习笔记(第三章之一)

    继续记笔记,JavaScript越来越有意思了. 继续... 第三章:JavaScript基础 ECMAScript语法在很大程度上借鉴了C和其它类似于C的语言,比如Java和Perl. 大小写敏感: ...

  9. python学习笔记(三)— 文件操作

    对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 现有以下文件a.txt: 登鹳雀楼 唐代:王之涣 白日依山尽,黄河入海流. 一.文件基 ...

  10. o'Reill的SVG精髓(第二版)学习笔记——第三章

    第三章:坐标系统 3.1视口 文档打算使用的画布区域称作视口.我们可以在<svg>元素上使用width和height属性确定视口的大小.属性的值可以是一个数字,该数字会被当作用户坐标下的像 ...

随机推荐

  1. 转载~基于比较的排序算法的最优下界为什么是O(nlogn)

    基于比较的排序算法的最优下界为什么是O(nlogn) 发表于2013/12/21 16:15:50  1024人阅读 分类: Algorithm 1.决策二叉树 回答这个问题之前我们先来玩一个猜数字的 ...

  2. (未解决)WIN8下使用POWERSHELL安装python easy_install无法成功

    按照https://pypi.python.org/pypi/setuptools#windows-8-powershell介绍的方法, 安装未成功.安装似乎没有启动, 也未安装成功. Windows ...

  3. SQLite 字段数据类型

    一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断. SQLite具有以下五种数据类型: 1.NULL:空值. 2.INTEGER:带符号的整型,具体取决有存入 ...

  4. MySql实现分页查询的SQL,mysql实现分页查询的sql语句(转)

    http://blog.csdn.net/sxdtzhaoxinguo/article/details/51481430 摘要:MySQL数据库实现分页查询的SQL语句写法! 一:分页需求: 客户端通 ...

  5. python的优化机制与垃圾回收与gc模块

    python属于动态语言,我们可以随意的创建和销毁变量,如果频繁的创建和销毁则会浪费cpu,那么python内部是如何优化的呢? python和其他很多高级语言一样,都自带垃圾回收机制,不用我们去维护 ...

  6. Python的扩展接口[2] -> 动态链接库DLL[0] -> 动态链接库及辅助工具

    动态链接库 / Dynamic Link Library 目录 动态链接库简介 函数封装DLL 组件对象模型COM 如何判断.dll文件是COM还是DLL 辅助工具 1 动态链接库简介 / DLL I ...

  7. Redis2.8.7配置文件说明

    Redis master配置文件说明 daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes daemonize yes # 当redis在后台运 ...

  8. ThinkPHP的自动验证常用的正则

    ThinkPHP的自动验证常用的正则   ThinkPHP的自动验证机制是为了进行表单数据验证,验证可以支持function. callback.confirm.equal.unique和regex, ...

  9. Ubuntu 16.04将ISO镜像写入U盘

    sudo fdisk -l 查看U盘的路径,如/dev/sdc为U盘的位置,注意位置!注意这个不是挂载的位置. 然后准备好ISO文件,如放在/home/jim/abc.iso 然后输入 sudo dd ...

  10. 关于asp.net mvc中 weiui gallery中IOS 下不显示预览图片问题的解决方式

    IOS 下面不显示预览. 结果去掉了红框中的缓存部分 就可以显示了 备忘,也帮助一下需要的朋友 @*<meta http-equiv="pragma" content=&qu ...