什么是文件描述符?

Posted

技术标签:

【中文标题】什么是文件描述符?【英文标题】:What is file-descriptor? 【发布时间】:2017-04-13 08:51:36 【问题描述】:

在尝试学习套接字编程时,我看到了以下代码:

int sock;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

我浏览了手册页,发现套接字返回一个文件描述符。我曾尝试在这里搜索互联网和其他类似问题,但我无法理解文件描述符的真正含义。如果有人能用简单的语言解释文件描述符,那就太好了。

【问题讨论】:

我建议阅读有关网络编程等复杂主题的结构化介绍。如果您能负担得起一本书或可以访问图书馆,请阅读 Stevens 的 UNIX 环境中的高级编程。 如果您从事大量网络编程,请查看他的网络编程书籍。手册页非常适合作为参考,但对于了解整体想法很差。 【参考方案1】:

有两个相关的对象:文件descriptor和文件description。人们经常将这两者混淆,并认为它们是相同的。

文件 descriptor 是应用程序中的一个整数,它引用内核中的文件 description

文件描述 是内核中维护打开文件状态(其当前位置、阻塞/非阻塞等)的结构。在 Linux 文件中 描述struct file.

POSIX open():

open() 函数应建立文件和文件描述符之间的连接。它将创建一个引用文件的打开文件 description 和引用该打开文件 description 的文件 descriptor。其他 I/O 函数使用文件描述符来引用该文件。 path 参数指向命名文件的路径名。

open() 函数应返回指定文件的文件描述符,该文件描述符是当前未为该进程打开的最低文件描述符。打开的文件描述是新的,因此文件描述符不应与系统中的任何其他进程共享。

【讨论】:

"文件描述符是应用程序中的一个整数,它引用内核中的文件描述。"有多个文件描述符;它们都引用一个文件描述吗? @Keith dup为相同的描述创建一个新的描述符,不像open【参考方案2】:

文件描述符只是到文件的映射。您也可以说这些是指向进程正在使用的文件的指针。 FD 只是整数值,用作进程资源的指针。

每当一个进程启动时,一个正在运行的进程的条目就会被添加到/proc/<pid> 目录中。这是保存与流程相关的所有数据的地方。此外,在进程启动时,内核会为进程分配 3 个文件描述符,用于与称为 stdinstdoutstderr 的 3 个数据流进行通信。 linux 内核使用一种算法来始终创建具有最小可能整数值的 FD,因此这些数据流被映射到数字 012

假设在您的代码中您打开了一个要读取或写入的文件。这意味着进程需要访问资源,并且必须为这个新资源创建映射/指针。 为此,内核会在您的代码打开文件后立即自动创建一个 FD。

如果你运行ls -l /proc/<pid>/fd/,你会看到一个额外的FD创建在那里,ID为4(如果程序使用了其他资源,也可以是其他数字)

【讨论】:

【参考方案3】:

在 Unix/Linux 操作系统中,文件描述符是一个抽象指示符(句柄),用于访问文件或其他 IO(输入/输出)资源,例如管道或网络套接字。 通常,文件描述符索引到由 Linux/Unix 操作系统中的内核维护的每个进程的文件描述符表,然后索引 所有进程打开的文件的系统范围表,称为文件表。 该表记录了打开文件或其他资源的“模式” 对于以下操作(还有更多操作)

阅读 写作 附加 写作

可能还有其他模式。 它还索引到第三个称为 inode 表的表,该表描述了实际的底层文件。

【讨论】:

【参考方案4】:

我认为文件描述符是(间接的,更高级别的)指针,指向内核维护的不透明文件对象。

通常,当您处理由库维护的对象时,您会将指向您不应该取消引用和自己操作的对象的指针传递给库。

对于内核对象,这不仅仅是你不应该自己操作它们——实际上你不能,因为它们存在于你根本无法访问的不同地址空间中。而且由于它们位于不同的地址空间中,因此指针不会成为一种有意义的引用方式。

您需要一个令牌或句柄,内核将在内部将其解析为在内核地址空间中有意义的指针。文件描述符就是这样的整数形式的标记。

对于内核:

your_process_id + your_file_descriptor => kernels_file_object_pointer

(如果给定的文件描述符可能无法解析为给定进程的文件对象指针,则为 EBADF 错误)

【讨论】:

以上是关于什么是文件描述符?的主要内容,如果未能解决你的问题,请参考以下文章

什么是文件描述符?

nodeJs中为啥文件描述符fd是一个整数

【fd】Linux文件描述符

什么是文件描述符的“异常”?

文件描述符fd是什么?

什么是文件描述符,用简单的术语解释?