Linux 基础 I/O 深入解析
理解'文件'
在 Linux 系统编程中,首先要建立对'文件'的正确认知。
狭义与广义
狭义上,文件就是磁盘上的数据块。磁盘作为外设,其读写操作本质上就是 I/O(Input/Output)。但在 Linux 的广义视角下,一切皆文件。键盘、显示器、网卡、甚至进程间通信的管道,都被抽象成了文件对象。
这意味着开发者可以使用同一套 API 接口来操作绝大部分系统资源,极大地降低了开发复杂度。
文件操作的本质
从系统角度看,文件由属性(元数据)和内容组成。即使是 0KB 的空文件,也占用磁盘空间并拥有属性。
所有的文件操作,本质上是进程对文件的操作。虽然 C/C++ 库函数提供了便利,但底层的实现依赖于操作系统提供的系统调用接口。
这里需要区分两种状态的文件:
- 磁盘级(未打开):存在于存储介质上。
- 内存级(被打开):进程通过系统调用打开后,在内核中创建的数据结构。
本文重点讲解内存级的文件操作机制。
回顾 C 标准文件接口
在使用系统调用前,我们先快速回顾一下 C 标准库中的文件接口,这有助于理解两者的区别。
打开与关闭
fopen 是常用的入口函数,它返回一个 FILE * 指针。不同的模式决定了文件的读写权限和行为:
| mode | 含义 | 文件不存在时 | 文件存在时 | 写入方式 |
|---|---|---|---|---|
"r" | 只读 | 返回 NULL | 正常打开 | 不可写入 |
"w" | 只写(新建) | 新建文件 | 清空原内容 | 从头写入 |
"a" | 追加(只写) | 新建文件 | 保留内容,追加到末尾 | 只能末尾追加 |
关闭文件使用 fclose。
提示:可以通过
ls /proc/[进程 ID]/ -l查看当前运行进程的详细信息,其中cwd指向当前工作目录,exe指向启动进程的可执行文件路径。
读写函数
C 标准库提供了丰富的读写函数,如 fgetc, fgets, fread 等。它们处理的是字符流或格式化数据。
需要注意的是,写入字符串时不需要手动添加 \0,这是 C 语言的规定,而非文件系统的限制。如果强行写入会导致乱码。


