news 2026/4/18 8:05:56

linux系统IO

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
linux系统IO

第一阶段:重新认识“文件”

在写 C 语言时,你肯定用过fopen,fread,fwrite。但在操作系统眼里,文件远不止“读写”这么简单。

1. 文件的本质

文件 = 文件内容 + 文件属性

  • 内容:你写进去的 "Hello World"。
  • 属性 (元数据):文件名、大小、创建时间、拥有者、权限等。
  • 结论:创建一个 0kb 的空文件,它也是占磁盘空间的,因为要存它的属性
2. 谁在操作文件?

代码写在那如果不跑,是不会操作文件的。

只有当代码运行起来变成进程后,才是“进程在操作文件”。

所以,文件操作的本质,是 进程 (Process) 和 操作系统 (OS) 之间的一次对话(因为磁盘硬件是归 OS 管的,进程不能直接摸)。


第二阶段:库函数 vs 系统调用 (The Battle)

  • C 标准库函数 (Library Functions)
    • fopen,fclose,fwrite,fread...
    • 特点跨平台。你在 Windows 上写fopen能跑,在 Linux 上也能跑。因为 C 库帮你屏蔽了底层差异。
    • 带缓冲:这是关键!它自带一个用户级缓冲区(稍后详解)。
  • 系统调用接口 (System Calls)
    • open,close,write,read...
    • 特点不跨平台。这是 Linux 内核直接提供的接口(Windows 的 API 叫CreateFile)。
    • 无缓冲:直接把数据扔给内核,甚至直接写盘。

层级关系:


第三阶段:核心接口open详解

我们要重点学习open,因为所有的“黑魔法”(如O_APPEND追加、O_CREAT创建)都藏在它的参数里。

1. 函数原型

你需要包含<fcntl.h>

int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
2. 参数flags(位图标志位)

还记得我们在讲waitpid时提到的位图吗?这里也是一样的设计。Linux 用一个整数的不同比特位来表示不同的选项。

常用的标志(必须记住):

  • O_RDONLY:只读打开。
  • O_WRONLY:只写打开。
  • O_RDWR:读写打开。

(以上三个必须三选一)

  • O_CREAT:如果文件不存在,就创建它。(如果存在,直接打开)。
  • O_TRUNC截断 (Truncate)。如果文件存在,把它清空(长度变为 0)。
  • O_APPEND追加。写数据时自动加到文件末尾。

如何组合? 使用 按位或 (|)。

比如:O_WRONLY | O_CREAT | O_TRUNC 就等同于 C 语言的 fopen(..., "w")。

3. 参数mode(权限)

注意:只有当你使用了O_CREAT选项时,才必须传第三个参数mode

  • 作用:指定新创建文件的初始权限(如0666)。
  • 实际权限:记得我们讲 mkfifo 时说的 umask 吗?这里同理。

$$实际权限 = mode \ \& \ (\sim umask)$$

4. 返回值:文件描述符 (File Descriptor)
  • 成功:返回一个int(大于等于 0)。我们通常叫它fd
  • 失败:返回-1,并设置errno

第四阶段:代码实战 —— 手写fopen("w")

我们来写一段代码,直接使用系统调用来实现“向文件写入字符串”。

#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { // 场景:以写的方式打开,如果不存在就创建,如果存在就清空 // 这完全等价于 fopen("log.txt", "w"); // 设置 umask 为 0,保证我们要的权限不被过滤 umask(0); // 1. 打开文件 // 返回值 fd 就是那个神秘的整数 int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) { perror("open"); // 打印错误原因 return 1; } printf("Open success, fd: %d\n", fd); // 2. 写入数据 const char *msg = "hello system call\n"; // write(fd, 缓冲区, 字节数) // 注意:这里不需要 +1 把 '\0' 写进去,因为文件里不需要字符串结束符,那是C语言的规定 int count = 5; while(count--) { write(fd, msg, strlen(msg)); } // 3. 关闭文件 close(fd); return 0; }

编译运行

Bash

gcc sys_io.c -o sys_io ./sys_io cat log.txt

实验现象

  1. 你会看到屏幕打印Open success, fd: 3
  2. cat能看到文件内容。
  3. 关键问题:为什么fd3? 0, 1, 2 去哪了?

第五阶段:核心谜题 —— 文件描述符 (File Descriptor)

这是基础 IO 中最重要的概念,也是面试必考题。

1. 0, 1, 2 的秘密

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

  • 0 (Standard Input):标准输入(键盘),对应 C 语言的stdin
  • 1 (Standard Output):标准输出(显示器),对应 C 语言的stdout
  • 2 (Standard Error):标准错误(显示器),对应 C 语言的stderr

因为 0, 1, 2 被占用了,所以你新打开的文件自然就分到了3

2. fd 的本质:数组下标

fd 到底是什么?

在内核的 task_struct (PCB) 中,有一个指针指向 struct files_struct。

在这个结构体里,有一个指针数组 struct file* fd_array[]。

  • fd 就是这个数组的下标!
  • 当你调用open时,内核创建一个file结构体,把它填入数组中最小的空闲位置(比如 3),然后把下标 3 返回给你。
  • 当你调用write(3, ...)时,内核通过下标 3 找到对应的file结构体,从而找到文件。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/15 14:23:00

混合开发模式是救星还是坑?3个案例揭秘节省40万成本的秘诀

亲爱的小伙伴们&#xff0c;今天咱们来聊一个让无数企业又爱又恨的话题——混合开发模式&#xff01;&#x1f4bb;&#x1f680; 你是不是也经常听到“混合开发能省40万成本”的说法&#xff0c;心里直犯嘀咕&#xff1a;这到底是真香警告&#xff0c;还是隐藏的深坑&#xff…

作者头像 李华
网站建设 2026/4/8 21:52:57

让创业更有后劲,长沙用金融铺就“成长跑道”

近几年&#xff0c;关于年轻人创业的讨论很多&#xff0c;但按照一线创业人提供的经验来看&#xff0c;比起最初一刻的选择&#xff0c;更难的是后面一长段时间的坚持&#xff1a;项目怎么从实验室走到市场&#xff1f;第一笔订单之后&#xff0c;第二批设备钱从哪里来&#xf…

作者头像 李华
网站建设 2026/4/16 9:12:51

SQL必会必知整理-13-联结表

13.1 联结联结是利用SQL的SELECT能执行的最重要的操作&#xff0c;很好地理解联结及其语法是学习SQL的一个极为重要的组成部分。13.1.1 关系表外键为某个表中的一列&#xff0c;它包含另一个表的主键值&#xff0c;定义了两个表之间的关系。这样做的好处如下&#xff1a;信息不…

作者头像 李华
网站建设 2026/4/18 8:03:20

jQuery EasyUI 树形菜单 - 树形菜单添加节点

下面直接给你最实用、最常见的树形菜单添加节点方法&#xff0c;jQuery EasyUI 的 tree 组件支持超级灵活的动态添加节点&#xff08;新增根节点、新增子节点、插入同级节点等&#xff09;&#xff0c;复制粘贴就能用&#xff0c;领导最爱的“动态部门树新增、菜单管理新增节点…

作者头像 李华
网站建设 2026/4/16 18:32:09

AI智能体的核心引擎:知识库构建全流程详解(建议收藏)

本文详细介绍了AI知识库作为智能体"认知大脑"的核心价值&#xff0c;阐述了其三层组成要素&#xff08;事实层、规则层、语义层&#xff09;及与智能体的交互逻辑。通过未来智安的实践案例&#xff0c;展示了AI知识库如何实现快速威胁定位、持续学习沉淀和人机协同优…

作者头像 李华
网站建设 2026/4/16 14:23:03

四端互通与高并发:下一代即时通讯系统的核心技术解析

在当前数字化时代&#xff0c;即时通讯系统已成为人们日常沟通的重要工具。一套优秀的即时通讯解决方案需要实现PC端、Web端、iOS和Android四端无缝互通&#xff0c;同时能够应对海量用户并发访问的挑战。本文将深入探讨实现这一目标的核心技术方案。全平台覆盖的架构设计现代即…

作者头像 李华