什么是文件描述符?
What is file-descriptor?
在尝试学习socket编程时,看到了如下代码:
int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
我浏览了手册页,发现 socket returns 是一个文件描述符。我试过在这里搜索互联网和其他类似问题,但我不明白文件描述符到底是什么。如果有人能用简单的语言解释文件描述符,那就太好了。
有两个相关对象:文件描述符和文件描述。人们经常混淆这两者,认为它们是一样的。
文件描述符是你应用程序中的一个整数,它在内核中引用文件描述。
File description 是内核中维护打开文件状态(其当前位置,blocking/non-blocking 等)的结构。在 Linux 文件中 descripion 是 struct file
.
The open()
function shall establish the connection between a file and a file descriptor. It shall create an open file description that refers to a file and a file descriptor that refers to that open file description. The file descriptor is used by other I/O functions to refer to that file. The path argument points to a pathname naming the file.
The open()
function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process. The open file description is new, and therefore the file descriptor shall not share it with any other process in the system.
在Unix/Linux操作系统中,文件描述符是一个抽象的指示符(句柄),用于访问文件或其他IO(input/output ) 资源,例如管道或网络套接字。
通常一个文件描述符索引到一个由内核在 Linux/Unix OS 中维护的每个进程文件描述符 table,然后索引
进入所有进程打开的系统范围 table 文件,称为文件 table。
此 table 记录打开文件或其他资源的 "mode"
对于以下操作(还有更多操作)
- 阅读
- 写作
- 追加
- 写作
可能还有其他模式。
它还索引到第三个 table 称为索引节点 table,它描述了实际的底层文件。
我认为文件描述符是(间接的,更高级别的)指向内核维护的不透明文件对象的指针。
通常,当您处理由库维护的对象时,您会向库传递指向您不应该取消引用和操作的对象的指针。
对于内核对象,这不仅仅是因为您不应该自己操作它们——实际上您不能,因为它们位于您根本无法访问的不同地址 space。而且因为它们位于不同的地址 space,指针将不是一种有意义的引用它们的方式。
您需要一个令牌或句柄,内核将在内部将其解析为在内核地址 space 中有意义的指针。文件描述符就是这样的整数形式的标记。
对于内核:
your_process_id + your_file_descriptor => kernels_file_object_pointer
(如果给定的文件描述符可能无法解析为给定进程的文件对象指针,则出现 EBADF 错误)
文件描述符只不过是到文件的映射。您也可以说这些是指向进程正在使用的文件的指针。
FD 只是整数值,用作指向进程资源的指针。
每当进程启动时,运行ning 进程的条目就会添加到 /proc/<pid>
目录中。这是保存与流程相关的所有数据的地方。此外,在进程启动时,内核为进程分配 3 个文件描述符,用于与称为 stdin
、stdout
和 stderr
的 3 个数据流进行通信。
linux 内核使用一种算法始终创建具有尽可能低的整数值的 FD,因此这些数据流被映射到数字 0
、1
和 2
。
假设在您的代码中您打开了一个要读取或写入的文件。这意味着该进程需要访问资源并且它必须为这个新资源创建一个 mapping/pointer。
为此,一旦您的代码打开文件,内核就会自动创建一个 FD。
如果你 运行 ls -l /proc/<pid>/fd/
你会在那里创建一个额外的 FD,id 4
(如果程序使用了其他资源,也可以是其他数字)
在尝试学习socket编程时,看到了如下代码:
int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
我浏览了手册页,发现 socket returns 是一个文件描述符。我试过在这里搜索互联网和其他类似问题,但我不明白文件描述符到底是什么。如果有人能用简单的语言解释文件描述符,那就太好了。
有两个相关对象:文件描述符和文件描述。人们经常混淆这两者,认为它们是一样的。
文件描述符是你应用程序中的一个整数,它在内核中引用文件描述。
File description 是内核中维护打开文件状态(其当前位置,blocking/non-blocking 等)的结构。在 Linux 文件中 descripion 是 struct file
.
The
open()
function shall establish the connection between a file and a file descriptor. It shall create an open file description that refers to a file and a file descriptor that refers to that open file description. The file descriptor is used by other I/O functions to refer to that file. The path argument points to a pathname naming the file.The
open()
function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process. The open file description is new, and therefore the file descriptor shall not share it with any other process in the system.
在Unix/Linux操作系统中,文件描述符是一个抽象的指示符(句柄),用于访问文件或其他IO(input/output ) 资源,例如管道或网络套接字。 通常一个文件描述符索引到一个由内核在 Linux/Unix OS 中维护的每个进程文件描述符 table,然后索引 进入所有进程打开的系统范围 table 文件,称为文件 table。 此 table 记录打开文件或其他资源的 "mode" 对于以下操作(还有更多操作)
- 阅读
- 写作
- 追加
- 写作
可能还有其他模式。 它还索引到第三个 table 称为索引节点 table,它描述了实际的底层文件。
我认为文件描述符是(间接的,更高级别的)指向内核维护的不透明文件对象的指针。
通常,当您处理由库维护的对象时,您会向库传递指向您不应该取消引用和操作的对象的指针。
对于内核对象,这不仅仅是因为您不应该自己操作它们——实际上您不能,因为它们位于您根本无法访问的不同地址 space。而且因为它们位于不同的地址 space,指针将不是一种有意义的引用它们的方式。
您需要一个令牌或句柄,内核将在内部将其解析为在内核地址 space 中有意义的指针。文件描述符就是这样的整数形式的标记。
对于内核:
your_process_id + your_file_descriptor => kernels_file_object_pointer
(如果给定的文件描述符可能无法解析为给定进程的文件对象指针,则出现 EBADF 错误)
文件描述符只不过是到文件的映射。您也可以说这些是指向进程正在使用的文件的指针。
FD 只是整数值,用作指向进程资源的指针。
每当进程启动时,运行ning 进程的条目就会添加到 /proc/<pid>
目录中。这是保存与流程相关的所有数据的地方。此外,在进程启动时,内核为进程分配 3 个文件描述符,用于与称为 stdin
、stdout
和 stderr
的 3 个数据流进行通信。
linux 内核使用一种算法始终创建具有尽可能低的整数值的 FD,因此这些数据流被映射到数字 0
、1
和 2
。
假设在您的代码中您打开了一个要读取或写入的文件。这意味着该进程需要访问资源并且它必须为这个新资源创建一个 mapping/pointer。
为此,一旦您的代码打开文件,内核就会自动创建一个 FD。
如果你 运行 ls -l /proc/<pid>/fd/
你会在那里创建一个额外的 FD,id 4
(如果程序使用了其他资源,也可以是其他数字)