apue学习笔记(第三章 文件I/O)
本章开始讨论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)的更多相关文章
- The Road to learn React书籍学习笔记(第三章)
The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...
- 《DOM Scripting》学习笔记-——第三章 DOM
<Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...
- [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设
[HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
- [HeadFirst-JSPServlet学习笔记][第三章:实战MVC]
第三章 实战MVC J2EE如何集成一切 Java2企业版(Java 2 Enterprise Editon,J2EE)是一种超级规范.规定了servlets2.4,JSP2.0,EJB2.1(Ent ...
- python学习笔记——第三章 串
第三章 字符串学习 1.字符串不灵活, 它不能被分割符值 >>> format = "hello, %s. %s enough for ya?" >> ...
- c#高级编程第七版 学习笔记 第三章 对象和类型
第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...
- JavaScript高级编程学习笔记(第三章之一)
继续记笔记,JavaScript越来越有意思了. 继续... 第三章:JavaScript基础 ECMAScript语法在很大程度上借鉴了C和其它类似于C的语言,比如Java和Perl. 大小写敏感: ...
- python学习笔记(三)— 文件操作
对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 现有以下文件a.txt: 登鹳雀楼 唐代:王之涣 白日依山尽,黄河入海流. 一.文件基 ...
- o'Reill的SVG精髓(第二版)学习笔记——第三章
第三章:坐标系统 3.1视口 文档打算使用的画布区域称作视口.我们可以在<svg>元素上使用width和height属性确定视口的大小.属性的值可以是一个数字,该数字会被当作用户坐标下的像 ...
随机推荐
- Windows注册与删除mysql服务
1.删除服务: (1)采用windows自带的服务管理工具:参考:http://www.cnblogs.com/qlqwjy/p/8010598.html sc delete MySQL57 (2)m ...
- 使用 WideCharToMultiByte Unicode 与 UTF-8互转
1.简述 最近在发送网络请求时遇到了中文字符乱码的问题,在代码中调试字符正常,用抓包工具抓的包中文字符显示正常,就是发送到服务器就显示乱码了,那就要将客户端和服务器设置统一的编码(UTF-8),而我们 ...
- [BZOJ1017][JSOI2008]魔兽地图DotR 树形dp
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2597 Solved: 1010[Submit][ ...
- AC日记——[HNOI2012]永无乡 bzoj 2733
2733 思路: 启发式合并splay(n*log^2n): 来,上代码: #include <cstdio> #include <cstring> #include < ...
- (1)C#工具箱-公共控件1
公共控件 InitializeComponent() 先说下InitializeComponent()这个方法,它在form1.cs里调用这个方法对控件进行初始化,控件的方法要在这个方法之后,否则会因 ...
- HDU 4417 Super Mario (划分树)(二分)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 在CentOS 7上安装Node.js
一.安装1.进入官网下载最新版本https://nodejs.org/en/ 选择下载后上传或直接使用wget下载 wget https://nodejs.org/dist/v8.11.2/node- ...
- idea点击RUN启动报错: Broken configuration due to unavailable plugin or invalid configuration dat
今天照常打开idea,突然发现之前的启动配置出问题了,随后报了一个这个错: Run Configuration Error: Broken configuration due to unavailab ...
- 玩转Nuget服务器搭建(三)
前两篇已经介绍了如何打包.如何搭建nuget server web站点,接下来让我们介绍一下,如何在我们的vs中访问我们自己搭建的nuget服务器中的包. vs访问我们自己的nuget服务器中的包 ...
- Android使用FFMpeg实现推送视频直播流到服务器
背景 在过去的2015年中,视频直播页的新宠无疑是户外直播.随着4G网络的普及和覆盖率的提升,主播可以在户外通过手机进行直播.而观众也愿意为这种可以足不出户而观天下事的服务买单.基于这样的背景,本文主 ...