文件描述符基础
- Linux启动每个进程自动打开三个标准IO:
- 描述符0,stdin_fileon,标准输入
- 描述符1,stdout_fileon,标准输出
- 描述符2,stderr_fileon,标准错误
- 文件描述声明周期
- 创建:系统调用open(),socket(),pipe(),dup()等。
- 使用:使用read(),write(),lseek(),ioctl()操作
- 关闭:使用close()释放资源
- 文件描述符与文件表与inode关系
- 多个fd可以指向同一个文件表项
- 多个文件表项可以指向同一个inode(磁盘元数据:文件大小,权限,数据块指针)
系统调用介绍
| open() | 打开或创建文件,返回最小可以fd |
| close() | 关闭fd,释放资源 |
| dup(fd) | 复制fd,返回最小可用新fd |
| dup2(oldfd,newfd) | 将oldfd复制到newfd |
c语言代码
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> void show_fds(const char* msg) { printf("\n--- %s ---\n", msg); system("ls -l /proc/self/fd/"); } int main() { int fd1, fd2; // 显示初始文件描述符(应包含 0,1,2) show_fds("初始状态"); // 打开一个新文件,获取新的文件描述符 fd1 = open("testfile.txt", O_CREAT | O_RDWR | O_TRUNC, 0644); if (fd1 == -1) { perror("open"); exit(1); } show_fds("打开 testfile.txt 后"); // 使用 dup 复制文件描述符 fd2 = dup(fd1); if (fd2 == -1) { perror("dup"); close(fd1); exit(1); } show_fds("dup(fd1) 后"); // 向两个 fd 写入数据(应写入同一文件) write(fd1, "Hello from fd1\n", 16); write(fd2, "Hello from fd2\n", 16); // 关闭 fd1,fd2 仍应有效 close(fd1); show_fds("关闭 fd1 后"); // 使用 dup2 将 fd2 重定向到 stdout (1) dup2(fd2, STDOUT_FILENO); printf("这条消息会写入 testfile.txt!\n"); // 因为 stdout 已重定向 // 恢复 stdout?这里不恢复,直接关闭 close(fd2); show_fds("全部关闭后"); // 验证文件内容 printf("\n文件 testfile.txt 内容:\n"); system("cat testfile.txt"); // 清理 unlink("testfile.txt"); return 0; }实验结果
编译运行结果