当前位置: 首页 > news >正文

【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添加完整的重定向功能。

http://www.jsqmd.com/news/1025373/

相关文章:

  • 2026济南奢侈品包包回收行业白皮书,正规门店全域实测 - 薛定谔的梨花猫
  • 如何快速掌握Python量化投资分析:QuantStats完整指南
  • 金融行业数字化——解读金融数据库存算分离架构选型白皮书【附全文阅读】
  • Linux Pulseaudio深度解析之pa_context_set_sink_input_volume用流程与实战(五十九)
  • 2026内衬不锈钢复合管厂家到底哪家强 - 速递信息
  • 2026南昌公司变更避坑TOP榜单!股权/地址/法人变更均可 - 江西企服智库
  • 2026北京卡地亚手表回收深度测评,禹竞名奢汇变现首选,六大靠谱商家综合实力盘点 - 名奢变现站
  • EVM3588-B开发板+NPU+Qwen2.5-3B-Instruct(一)
  • 2026上海名包回收门店汇总:5家甄选好评门店,各有千秋 - 奢侈品回收测评
  • 2026上海爱马仕包包回收口碑榜:5家门店排名,收的顶位居前列 - 奢侈品回收测评
  • Java计算机毕设之基于 SpringBoot 的餐饮收支台账与票据管理系统设计 餐饮经营财务数据统计分析系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 消失模白膜烘干设备主流品牌客观盘点排行 - 互联网科技品牌测评
  • 苏州宠物店探店实拍,新手选购宠物避坑指南 - 园友3800037
  • 如何快速掌握物理信息神经算子(PINO):从入门到实践的完整教程
  • Havenlon哲学:创业是为一个无法被忽视的问题在寻找系统化出口
  • 2026 钐钴磁铁厂家推荐攻略,如何挑选靠谱钐钴磁铁源头生产厂家不踩坑 - 商业新知
  • 佛山冰箱维修漏水怎么办?2026年专业检修方案与平台对比分析 - 简单到家
  • 2026梅州中高端家装选品指南:本地服务商适配与案例参考 - 速递信息
  • 武汉黄金回收避坑指南:四种套路一次拆穿,帮你少走很多弯路 - 奢侈品回收测评
  • 【麒麟系统】软件 RAID、逻辑卷快照、逻辑卷镜像技术选型参考(Linux 运维实战)
  • 合肥南亚理工学校招生电话,热门专业,报名要求,收费标准,学校位置详情 - hflgzz
  • 037华夏之光永存:高端精密装备国产化技术方案 第037题 高端激光干涉仪、光栅尺纳米级精密测量整机系统
  • 晨起赶时间剃须刀排行:高效便携款横向盘点 - 互联网科技品牌测评
  • Microchip 2002年全球技术支持网络:嵌入式开发线下服务体系的经典剖析
  • 济南黄金回收全攻略:7 家正规门店盘点 + 避坑干货,闲置黄金变现不踩坑 - 薛定谔的梨花猫
  • 企业刑事合规律师事务所测评:三大行业合规整改方案与排名 - 品牌2026
  • go | 环境安装和快速入门
  • Camera Link 与 CoaXPress 技术对比 如何选择你的相机接口 - Hello
  • 2026年企业即时通讯软件怎么选?十款企业IM部署、安全与协同能力对比 - 小天互连即时通讯
  • 福州电视闪屏维修指南:简单到家工程师自检清单与避坑指南 - 简单到家