天天看点

open/close read/write lseek

open/close

文件描述符

一个进程启动之后,默认打开三个文件描述符:

#define  STDIN_FILENO     	0
#define  STDOUT_FILENO    	1
#define  STDERR_FILENO    	2
           

新打开文件返回文件描述符表中未使用的最小文件描述符, 调用open函数可以打开或创建一个文件, 得到一个文件描述符.

open函数

函数描述: 打开或者新建一个文件

函数原型:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
           

函数参数:

pathname:参数是要打开或创建的文件名,和fopen一样, pathname既可以是相对路径也可以是绝对路径。

flags :参数有一系列常数值可供选择, 可以同时选择多个常数用按位或运算符连接起来, 所以这些常数的宏定义都以O_开头,表示or。

**必选项:**以下三个常数中必须指定一个, 且仅允许指定一个。

O_RDONLY 只读打开

O_WRONLY 只写打开

O_RDWR 可读可写打开

以下可选项可以同时指定0个或多个, 和必选项按位或起来作为flags参数。可选项有很多, 这里只介绍几个常用选项:

O_APPEND 表示追加。如果文件已有内容, 这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。

O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode, 表示该文件的访问权限。

文件最终权限:mode & ~umask

O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。

O_TRUNC 如果文件已存在, 将其长度截断为为0字节。

O_NONBLOCK 对于设备文件, 以O_NONBLOCK方式打开可以做非阻塞I/O(NonblockI/O),非阻塞I/O。

函数返回值:

成功: 返回一个最小且未被占用的文件描述符

失败: 返回-1, 并设置errno值.

close函数

函数描述: 关闭文件

函数原型: `

函数参数: fd文件描述符

函数返回值:

成功返回0

失败返回-1, 并设置errno值.

需要说明的是,当一个进程终止时, 内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close, 在终止时内核也会自动关闭它打开的所有文件。但是对于一个长年累月运行的程序(比如网络服务器), 打开的文件描述符一定要记得关闭, 否则随着打开的文件越来越多, 会占用大量文件描述符和系统资源。

read/write

read函数

函数描述: 从打开的设备或文件中读取数据

函数原型:

*ssize_t read(int fd, void buf, size_t count);

函数参数:

fd: 文件描述符

buf: 读上来的数据保存在缓冲区buf中

count: buf缓冲区存放的最大字节数

函数返回值:

>0:读取到的字节数

=0:文件读取完毕

-1: 出错,并设置errno

write

函数描述: 向打开的设备或文件中写数据

函数原型:

函数参数:

fd:文件描述符

buf:缓冲区,要写入文件或设备的数据

count:buf中数据的长度

函数返回值:

成功:返回写入的字节数

错误:返回-1并设置errno

lseek

所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为cfo. cfo通常是一个非负整数, 用于表明文件开始处到文件当前位置的字节数. 读写操作通常开始于 cfo, 并且使 cfo 增大, 增量为读写的字节数. 文件被打开时, cfo 会被初始化为 0, 除非使用了 O_APPEND.

使用 lseek 函数可以改变文件的 cfo.

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

函数描述: 移动文件指针

函数原型:

函数参数:

fd:文件描述符

参数 offset 的含义取决于参数 whence:

如果 whence 是 SEEK_SET,文件偏移量将设置为 offset。

如果 whence 是 SEEK_CUR,文件偏移量将被设置为 cfo 加上 offset,offset 可以为正也可以为负。

如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。

函数返回值: 若lseek成功执行, 则返回新的偏移量。

lseek函数常用操作

文件指针移动到头部

获取文件指针当前位置

获取文件长度

lseek实现文件拓展

off_t currpos;

// 从文件尾部开始向后拓展1000个字节

// 额外执行一次写操作,否则文件无法完成拓展