1. 文件IO介绍
- 文件 IO 即非缓冲 IO(unbuffered I/O)
- 它的
read
和 write
都是调用内核中的系统调用
- 它比标准IO更加底层,因此使用文件IO库函数的代码比标准IO的移植性更差,且没有经过优化(例如缓冲区),多数情况下的性能表现更差
- 大多数文件IO的实现只须这五个函数:
open
, read
, wirte
, lseek
, close
2. 文件描述符
- 通常由
open
或者 create
创建,传递给 read
或者 write
使用
- 按照惯例,文件描述符
0
被默认关联给标准输入, 1
被关联给标准输出,文件描述符 2
被关联给标准错误 - 应当使用
<unistd.h>
中定义的 STDIN_FILENO
,STDOUT_FILENO
和 STDERR_FILENO
,而不是直接使用数字
- 变化范围为
0~OPEN_MAX-1
,早期的上限是 19 个,现在一般是 63 个
3. 函数 open 和 openat
#include <fcntl.h>
int open(const char *path, int oflag, ... /*mode_t mode*/);
int openat(int fd, const char *path, int oflag, ... /*mode_t mode*/);
成功返回文件描述符,错误,返回-1oflag
参数可用一个常量或者多个常量用 |
连接:O_RDONLY
只读打开O_WRONLY
只写打开O_RDWR
读写打开O_APPEND
追加方式打开O_CREAT
若不存在创建O_TRUNC
若存在则长度截断为 0
,即清空打开- ……
- 返回的文件描述符默认是最小的可用的数字(有其他方法获得指定数字)
path
参数如果是绝对路径,此时 openat
的 fd
参数被省略,效果等同 open
函数
path
参数如果是相对路径,fd
参数指出了相对路径在文件系统中的开始地址
4. 函数 creat
#include <fcntl.h>
int creat(const char *path, mode_t mode);
- 相当于
open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)
5. 函数 close
#include <unistd.h>
int close(int fd);
6. 函数 lseek
- 每个文件都有一个当前文件偏移量(current file offset)
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
whence
是一个常量,SEEK_SET
将偏移量设置为距离文件开始处 offset
个字节SEEK_CUR
将偏移量设置为当前值加上 offset
,可为负数SEEK_END
将偏移量设置为文件长度加上 offset
,可正可负
- 偏移量的设置记录在内核中,不进行任何 I/O 操作
- 空洞文件:将一个空文件的偏移量设置到指定大小,写入一个字符后保存,该文件将会在磁盘上占用掉指定的大小(比如迅雷下载文件),代码参考 APUE 第三版图 3-2
7. 函数 read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbytes);
8. 函数 write
参考资料