文件描述符是什么?

3

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

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

我翻阅了man页面并发现socket返回一个文件描述符。我尝试在互联网和其他类似的问题中搜索,但我无法理解文件描述符到底是什么。如果有人可以用简单的语言解释文件描述符,那就太棒了。


我建议阅读一份结构化的介绍,以了解像网络编程这样的复杂主题。如果你有能力购买一本书或者可以进入图书馆,那么请阅读Stevens的《UNIX环境高级编程》。如果你经常从事网络编程,请查看他的网络编程书籍。Man手册作为参考非常好,但不适合获取整体概念。 - Peter - Reinstate Monica
5个回答

17

有两个相关的对象:文件描述符和文件描述。人们经常混淆这两者并认为它们是相同的。

文件描述符是应用程序中的整数,它指向内核中的文件描述。

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

POSIX open()

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

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


文件描述符是应用程序中的整数,它指向内核中的文件描述。有多个文件描述符;它们是否都指向单个文件描述? - ki9
2
@Keith dup会为相同的描述符创建一个新的描述符,而open不会这样做。 - Maxim Egorushkin

4
在Unix/Linux操作系统中,文件描述符是一个抽象的指示器(句柄),用于访问文件或其他IO(输入/输出)资源,例如管道或网络套接字。通常情况下,文件描述符索引到Linux/Unix操作系统内核维护的每个进程文件描述符表中,该表进一步索引到所有进程打开的文件的系统范围文件表中。此表记录了文件或其他资源已使用以下操作之一打开的“模式”(还有更多操作):
  • 读取
  • 写入
  • 追加
  • 写入

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


4
文件描述符就是对文件的映射,也可以说它们是进程正在使用的文件的指针。
FDs只是整数值,它们作为进程资源的指针。
当进程启动时,运行进程的条目将添加到/proc/<pid>目录中。这里保存了与进程相关的所有数据。此外,在进程启动时,内核会为进程分配3个文件描述符,用于与称为stdinstdoutstderr的3个数据流进行通信。
Linux内核使用一种算法来始终创建具有最低可能整数值的FD,因此这些数据流被映射到数字012
例如,在代码中打开一个文件以进行读取或写入。这意味着进程需要访问资源,并且必须为此新资源创建映射/指针。
为此,内核会在代码打开该文件时自动创建FD。
如果运行ls -l /proc/<pid>/fd/,您将看到在那里创建了一个附加的FD,其ID为4(如果程序使用了其他资源,则也可能是其他数字)。

4

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

通常,当您处理库维护的对象时,会向库传递指向您不应自行引用和操作的对象的指针。

对于内核对象来说,不仅仅是因为您不应该自己操纵它们 - 因为它们存在于不可访问的不同地址空间中,所以您根本无法操纵它们。并且因为它们存在于不同的地址空间中,指针不会成为指向它们的有意义的方式。

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

对于内核:

your_process_id + your_file_descriptor => kernels_file_object_pointer

(��者如果给定的文件描述符不能被解析为给定进程的文件对象指针,则会出现EBADF错误)

0
  • 文件描述符是与打开文件相关联的数字。

  • 它就像是文件描述符表中的索引或条目号。

  • 文件描述符表是每个进程私有的,但也可以在进程之间共享。

  • 文件描述符表中的条目指向系统范围内的文件描述表中的条目。

  • 文件描述表中的条目包含有关文件的实际数据:访问模式偏移量状态标志,以及指向I-Node表中的条目的指针,该表保存有关存储介质上文件实际位置的信息(块编号)。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接