逻辑书写
请写下你的逻辑,与参考逻辑对比,如有缺失,可细看本文
一、核心API清单
#include <fcntl.h> // open()的标志位定义
#include <unistd.h> // read/write/close/lseek
// 关键系统调用原型
int open(const char *pathname, int flags, mode_t mode);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);
int close(int fd);
二、函数详解
- open() - 文件门户
// 创建新文件(若存在则清空)
int fd = open("data.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
flags
组合示例:O_RDONLY
:只读(默认)O_WRONLY | O_APPEND
:追加写入O_EXCL
:与O_CREAT
联用,确保原子创建
- read()/write() - 数据传输
char buffer[1024];
ssize_t bytes_read = read(fd_in, buffer, sizeof(buffer));
ssize_t bytes_written = write(fd_out, buffer, bytes_read);
- 返回值处理原则:
-
0:实际读写的字节数
- 0:EOF(仅read)
- -1:错误(需检查errno)
-
- lseek() - 文件指针导航
// 定位到文件末尾
off_t pos = lseek(fd, 0, SEEK_END);
- 特殊用法:
lseek(fd, 0, SEEK_CUR)
获取当前位置lseek(fd, -100, SEEK_END)
倒数第100字节
- close() - 资源释放
if (close(fd) == -1) {
perror("关闭文件失败");
}
- 未关闭的文件描述符会导致资源泄漏
- 进程退出时自动关闭,但显式关闭是良好习惯
四、深入理解要点
-
文件描述符本质:
- 非负整数,进程级文件表索引
- 0:stdin, 1:stdout, 2:stderr
-
缓冲机制差异:
- 标准库函数(fread/fwrite)带用户缓冲
- 系统调用直接内核交互,更底层高效
-
错误处理模式:
if ((fd = open(...)) == -1) { perror("open failed"); exit(EXIT_FAILURE); }
五、典型应用场景
- 日志滚动记录(结合O_APPEND)
- 大文件随机访问(lseek定位)
- 设备文件操作(如操作/dev/uinput)
- 文件锁实现(配合fcntl)
建议通过strace
工具观察系统调用执行过程:
$ strace -e trace=open,read,write ./file_demo
file_demo.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("demo.txt", O_RDWR | O_CREAT, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
const char *msg = "Hello POSIX!\n";
write(fd, msg, strlen(msg));
lseek(fd, 0, SEEK_SET); // 重置文件指针
char buf[256];
ssize_t len = read(fd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, len); // 输出到终端
close(fd);
return 0;
}
FO
是一个文件描述符,它应该之前已经通过 open 函数打开了一个文件,并且获得了该文件的文件描述符。
0
是偏移量,表示不移动位置。
SEEK_SET
是基准点,表示从文件开头开始计算偏移量。
终端操作
# 编译执行
$ gcc -o file_demo file_demo.c
$ ./file_demo
Hello POSIX!
# 查看生成文件
$ ls -l demo.txt
-rw-r--r-- 1 user group 13 Jun 1 10:00 demo.txt
参考逻辑
- 打开文件
- 异常处理
- 写入文件
- 读取文件
- 关闭文件