news 2026/6/16 20:09:32

【Linux】系统级文件I/O与文件描述符深度剖析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Linux】系统级文件I/O与文件描述符深度剖析

目录

1. 引言

2. 系统调用接口

2.1 open 函数

2.2 write 与 read

2.3 close

3. 文件描述符(File Descriptor, fd)

3.1 默认打开的三个文件描述符

3.2 文件描述符的本质

3.3 文件描述符分配规则

4. 重定向的原理

4.1 输出重定向示例

4.2 使用 dup2 系统调用

5. 小结


1. 引言

C标准库的fopen等函数最终调用的是系统调用。本文直接使用系统调用接口openreadwriteclose进行文件操作,并重点讲解文件描述符的概念、分配规则以及重定向的底层原理。

2. 系统调用接口

2.1open函数

c

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);

参数:

  • pathname:文件路径。

  • flags:必须包含O_RDONLYO_WRONLYO_RDWR之一,可与其他标志按位或,如O_CREAT(不存在则创建)、O_APPEND(追加)、O_TRUNC(截断)。

  • mode:当使用O_CREAT时,指定新文件的权限(如0644),会受到进程umask的影响。可通过umask(0)临时清除掩码。

返回值:成功返回一个非负整数——文件描述符;失败返回 -1。

2.2writeread

c

ssize_t write(int fd, const void *buf, size_t count); ssize_t read(int fd, void *buf, size_t count);
  • fd:文件描述符。

  • 返回值:成功返回实际读/写的字节数,出错返回 -1。

2.3close

c

int close(int fd);

关闭文件描述符,释放相关资源。

3. 文件描述符(File Descriptor, fd)

3.1 默认打开的三个文件描述符

Linux进程启动时,默认打开三个文件描述符:

  • 0:标准输入(stdin)

  • 1:标准输出(stdout)

  • 2:标准错误(stderr)

它们对应的物理设备通常是键盘和显示器。我们可以直接使用read(0, buf, size)从键盘读入,使用write(1, buf, len)输出到屏幕。

3.2 文件描述符的本质

文件描述符是一个小整数,它是进程打开文件表的索引。内核为每个进程维护一个files_struct结构体,其中包含一个指针数组fd_array[],每个元素指向一个struct file对象(表示一个打开的文件)。文件描述符就是这个数组的下标。

3.3 文件描述符分配规则

规则:在当前进程中,fd_array[]中找到最小的未被使用的下标,分配给新打开的文件。

验证实验:

  • 正常打开一个文件,输出fd通常为3(因为0、1、2已被占用)。

  • 先调用close(0)close(2),再打开文件,则新文件的fd将成为02

4. 重定向的原理

4.1 输出重定向示例

c

close(1); // 关闭标准输出 int fd = open("myfile", O_WRONLY | O_CREAT, 0644); printf("fd: %d\n", fd); // 这里 fd 为 1 fflush(stdout);

现象:printf的内容没有出现在屏幕上,而是写入了myfile文件。这是因为close(1)释放了下标1,随后open分配了最小的可用下标1,于是文件描述符1现在指向了myfile对应的struct fileprintf底层向stdout(即 fd=1)写入数据,数据便进入了文件。

重定向的本质:改变文件描述符下标对应的struct file指针,使其指向不同的打开文件。

4.2 使用dup2系统调用

dup2可以更便捷地实现重定向:

c

#include <unistd.h> int dup2(int oldfd, int newfd);

功能:让newfd指向oldfd所指向的文件,如果newfd已打开,则先关闭它。

示例:实现输出重定向

c

int fd = open("log", O_CREAT | O_RDWR, 0644); dup2(fd, 1); // 将标准输出重定向到 fd 对应的文件 printf("这条消息将写入 log 文件\n");

同理,输入重定向使用dup2(fd, 0),追加重定向使用O_APPEND标志打开文件后再dup2

5. 小结

本文详细介绍了系统级文件I/O接口、文件描述符的概念、分配规则以及重定向的底层原理。下一篇我们将把这些知识应用到之前实现的迷你Shell中,为Shell添加完整的重定向功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 20:06:00

Linux:TCP协议的socket套接字

目录 服务端 init()初始化方法 start()运行方法 收发数据&#xff1a; main() 客户端 init()初始化方法 start()运行方法 main() 完善日志打印 多进程版 多线程版 守护进程 Deamon()实现 关于套接字的介绍&#xff0c;可以移步到下面这篇文章&#xff1a; Linux…

作者头像 李华
网站建设 2026/6/16 20:01:03

Codex:Mac终端原生AI智能体,本地化CLI Agent实战指南

1. 项目概述&#xff1a;Codex不是另一个AI工具&#xff0c;而是让你告别工具追逐战的“终端智能体”Codex——这个名字最近在开发者圈子里反复刷屏&#xff0c;但很多人点开搜索结果后反而更困惑了&#xff1a;它到底是OpenAI早年那个已下线的代码生成模型&#xff1f;是GitHu…

作者头像 李华
网站建设 2026/6/16 19:57:10

从零到爆款:3分钟让AI帮你搞定专业短视频创作

从零到爆款&#xff1a;3分钟让AI帮你搞定专业短视频创作 【免费下载链接】MoneyPrinterTurbo 利用AI大模型&#xff0c;一键生成高清短视频 Generate short videos with one click using AI LLM. 项目地址: https://gitcode.com/GitHub_Trending/mo/MoneyPrinterTurbo …

作者头像 李华
网站建设 2026/6/16 19:53:23

【智能硬件出海合规·第04篇】Design for Compliance (DFC) 实战:将认证约束注入原理图与 Layout

第四章 Design For Compliance (DFC) 引言:为何小 CEO 和架构师必须死守 DFC 红线? 新产品开发周期中,最昂贵的代价除了模具报废,就是研发后期的重新打板(Respin)与认证失败导致的延期。 小 CEO 的视角:根据行业统计,70% 的 IoT 产品在第一次进入正规 EMC 或射频实验…

作者头像 李华
网站建设 2026/6/16 19:51:02

ROFL-Player:英雄联盟回放播放器终极解决方案

ROFL-Player&#xff1a;英雄联盟回放播放器终极解决方案 【免费下载链接】ROFL-Player (No longer supported) One stop shop utility for viewing League of Legends replays! 项目地址: https://gitcode.com/gh_mirrors/ro/ROFL-Player 想要重温英雄联盟的精彩对局&a…

作者头像 李华