Linux 文件 I/O 基础概念
Linux 采用"一切皆文件"的设计理念,所有设备通过统一的文件描述符机制进行访问。文件描述符是非负整数,用于标识已打开的文件。系统默认保留 0(stdin)、1(stdout)、2(stderr),新文件描述符从 3 开始分配。
核心系统调用函数
open() 函数
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);
- 典型 flags 组合:
O_RDWR | O_CREAT | O_TRUNC - 创建文件时需指定权限模式(如
0644) - 返回文件描述符或 -1(失败)
read/write 操作
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
- 需检查返回值:实际传输字节数可能小于请求值
- 文件末尾时 read() 返回 0
- 错误时返回 -1 并设置 errno
文件定位控制
off_t lseek(int fd, off_t offset, int whence);
- whence 参数:
SEEK_SET(文件头)、SEEK_CUR(当前位置)、SEEK_END(文件尾) - 可获取当前偏移量:
lseek(fd, 0, SEEK_CUR)
最佳实践要点
错误处理规范
每个系统调用后应检查返回值,配合 perror() 输出错误信息:
if (close(fd) == -1) {
perror("close error");
exit(EXIT_FAILURE);
}
缓冲区管理
- 推荐缓冲区大小通常为 4KB(与文件系统块大小对齐)
- 循环读写时应使用实际传输字节数:
while ((n = read(fd, buf, BUF_SIZE)) > 0) {
if (write(out_fd, buf, n) != n) {
/* 处理写入不完整 */
}
}
高级特性
原子操作保证
- 使用
O_APPEND确保多进程追加写入的原子性 O_EXCL与O_CREAT组合实现独占创建
非阻塞I/O模式
通过 fcntl() 设置 O_NONBLOCK:
int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
文件元数据操作
需配合 fstat() 获取文件信息:
struct stat st;
fstat(fd, &st);
printf("File size: %ld\n", st.st_size);
性能优化建议
- 大文件操作时使用
posix_fadvise()预声明访问模式 - 频繁小数据量写入考虑使用
writev()分散聚集I/O - 关键路径避免多次系统调用,优先使用批量操作
标准I/O库对比
系统调用与标准库函数的选择依据:
- 需要精细控制时使用系统调用
- 需要缓冲机制时使用
fopen()/fread()系列 - 混合使用时注意使用
fileno()转换FILE*
1290

被折叠的 条评论
为什么被折叠?



