当前位置: 首页 > 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.gsyq.cn/news/1537238.html

相关文章:

  • 金融行业数字化——解读金融数据库存算分离架构选型白皮书【附全文阅读】
  • EVM3588-B开发板+NPU+Qwen2.5-3B-Instruct(一)
  • 2026上海名包回收门店汇总:5家甄选好评门店,各有千秋 - 奢侈品回收测评
  • 合肥南亚理工学校招生电话,热门专业,报名要求,收费标准,学校位置详情 - hflgzz
  • 佛山冰箱维修漏水怎么办?2026年专业检修方案与平台对比分析 - 简单到家
  • 武汉黄金回收避坑指南:四种套路一次拆穿,帮你少走很多弯路 - 奢侈品回收测评
  • go | 环境安装和快速入门
  • Nano Banana Pro:专业级AI图像生成的四大底层突破
  • 2026年宁波减肥训练营2026宁波封闭式减肥训练营深度实测:吃住全包 + 签约减重,东吴这家营地凭实力打破行业乱象 - 速递信息
  • 海口家电维修平台服务对比:2026年行业数据驱动的消费决策参考 - 简单到家
  • 无锡哪家宠舍靠谱 7家实地探访给出答案 - 园友3800037
  • OpenClaw本地AI工作流部署全解析:PowerShell、Ollama镜像与Qwen3.5:9b实战
  • 【问答】青岛防水维修一般质保多久?不同部位质保标准参考 - 青岛防水品牌推荐
  • Python 数据分析实战:Pandas+Matplotlib 从入门到可视化报表
  • 解锁AI写专著密码!AI专著撰写工具,20万字专著快速成型!
  • 2026实测推荐:小红书视频怎么去水印?复制链接就能解析保存的3个小程序 - 效率工具研究所
  • 20251202马思钊 2025-2026-2 实验四 Python综合实践
  • 新手在无锡买猫狗 哪家宠物门店值得信赖? - 园友3800037
  • BallonTranslator:让漫画翻译变得像聊天一样简单的AI工具
  • 2026 粘结钕铁硼厂家推荐|高精度异形磁体定制,新能源电机磁瓦生产厂商 - 商业新知
  • Steam Deck控制器Windows驱动完全指南:SWICD让你的游戏体验无缝衔接
  • 2026 好用的素颜霜早八通勤实测|100 人 28 天横评榜单 黄皮自然抗暗沉优选 - 速递信息
  • 2026银行秋招面试技巧班深度评测:4家头部机构对比,谁能帮你突破最后一关 - 互联网科技品牌测评
  • 杭州购宠避坑指南:4家靠谱实体门店实测推荐 - 园友3800037
  • 2026银行网申修改机构横向评测:精准适配不同考生,破解网申死难题 - 互联网科技品牌测评
  • 无锡购宠避坑指南 7家正规实体繁育门店实测推荐 - 园友3800037
  • 北京卖表必看!全网高口碑奢侈品名表回收门店测评|本地6大商家客观排名 - 名奢变现站
  • 长沙雨花区下水道疏通 2026 真实评测最新综合排行榜 - 居顺联家政疏通
  • 二手欧米茄出手别乱询价,2026南京正规回收门店报价透明实测 - 奢侈品回收评测
  • Rescuezilla终极指南:3个简单步骤实现系统备份与恢复