APUE第三章 文件I/O
1、文件描述符
对于内核而言,所有打开的文件都通过文件描述符引用。文件描述符是打开或者创建文件的时候,内核向进程返回的一个非负整数。UNIX系统中,一般用0,1,2分别表示标准输入,标准输出和标准出错。一个系统的文件描述符变换范围在0~OPEN_MAX。在linux系统中,可以使用
cat /proc/sys/fs/file-max
查看最大描述符数量,并且可以根据需要修改这个数值。
2、open函数
#include <fcntl.h>
int open(const char *filename, int oflag);int open(const char *filename, int oflag, mode_t mode);
描述:该函数根据oflag模式打开文件名为filename的文件,并返回打开的文件描述符。
其中oflag来说明此函数的多个选项,有以下取值:
O_RDONLY 只读打开
O_WRONLY只写打开
O_RDWR 读写打开
这三个常量必须指定且只能指定一个,下面的常量是可选的:
O_APPEND 写时追加
O_CREAT 文件若不存在,就创建
O_EXCL 如果指定了O_CREAT,且文件已经存在,就会出错,用来测试一个文件是否存在
O_TRUNC 文件存在,而且只写或读写打开成功,就将其长度截断为0
O_NOCTTY 若pathname是终端设备,则不将该设备分配作为此进程的控制终端
O_DSYNC 使每次write等待物理I/O操作完成,但是如果写操作并不影响读取刚写入的数据,则不等待文件属性更新
O_RSYNC 使每一个文件描述符作为参数的read操作等待,直至任何对文件同一部分进行的未决写操作都完成
3、creat函数
#include <fcntl.h>
int creat(const char *filename, mode_t mode);
描述:以只写方式打开一个创建的新文件
如果要以可读写方式打开一个创建的新文件,可以使用
open(pathname,O_RDONLY | O_CREAT | O_TRUNC,mode)
4、close函数
#include <unistd.h>
int close(int filedes);
关闭指定的文件描述符。同时,如果进程在此文件上加有记录锁,将释放。在进程终止时,内核将自动关闭进程打开的文件。
5、lseek函数
#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
描述:每个打开的文件都有一个与之相关的文件偏移量,用于度量从文件开始处的字节数,可以用lseek显式的为一个打开的文件设置偏移量。三个参数分别是文件描述符,偏移,和设置偏移方式。执行成功返回新的文件偏移量。
其中偏移方式有一下选项:
- 若whence是SEEK_SET,则文件偏移量是从开始到距文件开始处offset个字节。
- 若whence是SEEK_CUR,则改文件的偏移量设置为当前值加offset,offset可正可负。
- 若whence是SEEK_END,则该文件的偏移量设置为文件长度加上offset,offset可正可负。
off_t currpos;
currpos = lseek(fd,0,SEEL_CUR)
文件偏移量可以大于文件长度,在这种情况下,下次对该文件的读写将会形成空洞,并用0填充,但是对于空洞部分不占用磁盘块。
6、read函数
#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
描述:根据文件描述符读取文件,read成功,返回读到的字节数。
7、write函数
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
描述:根据文件描述符往文件里写,对于普通文件,写从当前偏移处开始,若打开指定了O_APPEND选项,则文件偏移量设置在文件的结尾处。
8、pread和pwrite函数
#include <unistd.h>
ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);
描述:相当于顺序执行lseek和read或者write操作,但是这两个操作是原子操作。
9、dup和dup2函数
#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
描述:复制文件描述符,dup使用当前可用文件描述符表中的最小值引用需要复制文件描述符的文件。dup2使filedes2指定新描述符的数值。如果filees已经打开,则先将其关闭。若filedes2==fildes,则返回filedes2,但是不关闭它。
10、sync、fsync和fdatasync函数
#include <unistd.h>
int fsync(int filedes);
int fdatasync(int filedes);
void sync(void);
描述:sync将所有的块缓冲区排入写队列然后返回,不等待实际磁盘写结束。
fsync只对指定的filedes文件描述符起作用,并且等待磁盘操作结束。
11、fcntl函数
#include <fcntl.h>
int fcntl(int filedes, int cmd, /* int arg*/);
描述:改变打开文件的性质。包括:
- 复制一个现有的文件描述符
- 获得/设置文件描述符
- 获得/设置文件状态标记
- 获得/设置异步I/O所有权
- 获得/设置记录锁
其中cmd具有以下选项:
- F_DUPFD 赋值文件描述符filedes,返回新的可用文件描述符中的最小值。新的描述符与filedes共享同一文件表项,但是新的描述符在进程表里有自己的文件描述符标志,其FD_CLOEXEC文件描述符标志被清除。
- F_GETFD 返回文件描述符
- F_SETFD 设置文件描述符,新的参数按照第三个参数设置
- F_GETFL 返回文件状态标志
- F_SETFL 设置文件状态标志
- F_GETOWN 返回当前接收SIGIO和SIGURG信号的进程ID或者进程组ID
- F_SETOWN 设置当前接收SIGIO和SIGURG信号的进程ID或者进程组ID
- 文件描述符标志(close_on_exec)
- 指向一个文件表项的指针
- 文件状态标志(读、写、添加、同步和非阻塞等)
- 当前文件偏移量
- 指向该文件v节点表项的指针