为什么会有「一切皆文件」这句话?
回到 Unix 诞生的年代(1969 年)。那时候每种 I/O 设备都自带一套专用接口——磁带机有自己的指令、打印机有自己的指令、终端有自己的指令。程序员要和 N 种设备打交道,就得学 N 套接口;每接一种新设备,又得重学一套。
这很痛苦。Unix 的设计者问:能不能让所有东西用同一套方式访问?
答案就是「一切皆文件」——把所有 I/O 对象都包装成「文件」,用同一套接口去操作它们。
一个类比:USB 接口。 USB 出现之前,键盘用 PS/2 口、打印机用并口、鼠标用串口,每种设备一个专用插头。USB 把它们统一成一个口——你不用关心插的是键盘还是 U 盘,接口长得一样。「一切皆文件」就是 Unix 版的 USB:统一插口,不管设备。
所以这句话真正想表达的是:
不是「所有东西都是磁盘上的文件」,而是「所有 I/O 对象,都用同一套方式访问」。
什么才算 Linux 里的「文件」
在 Linux 里,下面这些都叫「文件」,都能用一个 fd(文件描述符)引用、用 read/write 读写:
| | |
|---|
| a.txt、/bin/ls | |
| /home、/etc | |
| /dev/null、/dev/tty | |
| /dev/sda | |
| pipe() | |
| | |
| /proc/cpuinfo、/sys/... | |
最后一类最反直觉:/proc/cpuinfo 根本不在磁盘上。你 cat /proc/cpuinfo 时,是在问内核「CPU 信息是什么」,内核现编现答给你一段文字。但因为这段文字长得像文件、用 read 读,所以你不用学新接口——cat 照样能看。
一切皆文件,到底「统一」了什么?
不管对象是上面哪一种,访问它的系统调用都是同一套:
| |
|---|
open() | |
read() | |
write() | |
close() | |
ioctl() | |
poll/select/epoll | |
关键:你 open() 一个路径,拿回一个 fd;之后 read/write 只认 fd,不再关心 fd 背后到底是磁盘文件、设备还是管道。

再深化一下这个类比:
你写一个程序 copy A B(从 A 读、往 B 写)。如果 A 是磁盘文件、B 是屏幕,和 A 是键盘、B 是网络,代码完全一样——都是 read(A) → write(B)。这就是统一接口的威力:「做什么」和「接的是谁」彻底解耦了。程序只管读写,不关心对面是谁。
统一的是接口,不是对象
所以要纠正一个直觉:「一切皆文件」统一的不是对象——普通文件还是普通文件、设备还是设备、管道还是管道,它们本质上完全不同。
Linux 做的只是:让它们对外长得一样,都套上同一套接口的外壳。
那内核是怎么做到「让完全不同的东西套上同一个外壳」的?这是下篇的内容——内核的把戏 VFS。