Appearance
题目
以下系统调用中,包含文件按名查找功能的系统调用是( )。
错因
B
以为"读文件需要找文件"。但 read(fd, buf, n) 的第一个参数是 fd(整数),fd 是 open 时分配好的下标,内核直接用 fd 在打开文件表里 O(1) 查到文件信息——根本不需要再走目录树查找。"按名查找"只在 open 时做一次。
C
同 B 的思路。write(fd, ...) 用的也是 fd,路径解析早在 open 时就完成了,写操作直接走 fd 索引。
D
以为关闭文件需要按名找它。close(fd) 只需把 fd 对应的打开文件表项标记为空闲、引用计数减 1——根本不涉及目录查找。fd 的存在就是为了消除重复查找——如果每次 read/write/close 都要重新按名查找一遍,效率会非常低。
总解析
核心:搞清"按名查找"发生在哪个系统调用——只在打开文件时进行一次。
文件操作流程:
open("/path/to/foo.txt", ...) ← 字符串路径
↓ 按名查找:解析路径 → 遍历目录树 → 定位 inode → 分配 fd
fd = 3 ← 后续都用 fd(数字)
↓
read(fd=3, ...) ← 按 fd 索引打开文件表,O(1) 直查
write(fd=3, ...) ← 同上
close(fd=3) ← 释放表项为什么这样设计:
- "按名查找"涉及目录遍历,开销大(多次磁盘 I/O 读目录块、字符串比较)
- 一次 open 后,把查找结果缓存在内核打开文件表里
- 后续 read/write/close 全部用 fd(小整数下标),跳过目录树——这正是 fd 设计的根本目的
逐项核对:
| 系统调用 | 参数类型 | 是否按名查找 |
|---|---|---|
| open | 字符串路径 | ✓ 必须 |
| read | fd(整数) | ✗ 直查打开文件表 |
| write | fd(整数) | ✗ 同上 |
| close | fd(整数) | ✗ 同上 |
速记:参数是"路径名"的才需要按名查找,参数是"fd"的不需要。题中只有 open 接收路径名。
最终答案是 A。