# 文件描述符

![](https://drawings.jvns.ca/drawings/filedescriptors.jpeg)

## 什么是文件描述符？

文件描述符（File Descriptor）是内核为了管理已经打开的文件而创建的索引。它是一个非负整数，在形式上表现为一个整数。在Linux系统中，所有对设备的操作、对文件的操作都可以通过文件描述符来进行。

## 标准文件描述符

Linux系统为每个进程自动打开三个标准文件描述符：

* **0** - 标准输入（stdin） - 默认连接到键盘
* **1** - 标准输出（stdout） - 默认连接到终端屏幕
* **2** - 标准错误（stderr） - 默认连接到终端屏幕

## 文件描述符的工作原理

当进程打开文件时，内核会：

1. 在文件描述符表中寻找一个空闲的条目
2. 为该文件分配一个文件描述符（一个小的非负整数）
3. 在文件表中创建一个条目，包含文件的访问模式、当前位置等信息
4. 返回文件描述符给进程

## 文件描述符的范围

* **0-2**: 保留给标准输入、标准输出和标准错误
* **3-9**: 可用于用户自定义的文件描述符
* **10及以上**: 通常用于程序内部使用

## 文件描述符与I/O重定向

文件描述符是I/O重定向的基础。通过重定向，我们可以：

* 将标准输出重定向到文件
* 将标准错误重定向到文件
* 将标准输入重定向从文件读取
* 在文件描述符之间进行复制

## 示例

```bash
# 查看当前进程的文件描述符
$ ls -la /proc/self/fd/

# 创建新的文件描述符
$ exec 3< input.txt    # 打开文件用于读取，文件描述符为3
$ exec 4> output.txt   # 打开文件用于写入，文件描述符为4

# 使用文件描述符
$ cat <&3              # 从文件描述符3读取
$ echo "hello" >&4     # 写入到文件描述符4

# 关闭文件描述符
$ exec 3<&-           # 关闭文件描述符3
$ exec 4>&-           # 关闭文件描述符4
```

## 文件描述符的限制

每个进程都有文件描述符数量的限制，可以通过以下命令查看：

```bash
# 查看系统限制
$ ulimit -n

# 查看进程当前打开的文件描述符数量
$ ls /proc/<PID>/fd/ | wc -l
```

## 系统调用

常用的文件描述符相关系统调用：

* `open()` - 打开文件，返回文件描述符
* `close()` - 关闭文件描述符
* `read()` - 从文件描述符读取
* `write()` - 写入到文件描述符
* `dup()` - 复制文件描述符
* `fcntl()` - 操作文件描述符属性

## 参考资料

* [Linux 文件描述符详解](https://man7.org/linux/man-pages/man2/open.2.html)
* [Julia's Drawings: File Descriptors](https://drawings.jvns.ca/filedescriptors/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.cdxiaodong.life/linux-an-quan/overview/file-descriptor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
