文件描述符是什么,简单解释一下?

607
  1. 相较于维基百科,文件描述符的更简化描述是什么?它们为什么是必须的?以shell进程为例,它如何应用?

  2. 进程表是否包含多个文件描述符?如果是,为什么?


4
stdin、stdout和stderr等概念是什么?比如,我有一个浏览器进程打开了一些临时文件来显示我的HTML页面。该进程是否使用相同的fd来读/写这些文件?还有,进程表中的条目……它们具有fd0指针、fd1指针、fd2指针等,这是否意味着所有这些文件都在RAM中?否则为什么要用指针? - Nishant
87
打开文件时,操作系统会创建一个流并将该流连接到打开的文件上,描述符实际上代表了该流。同样地,操作系统也创建了一些默认流,这些流连接到终端而非文件上。因此,当您在终端中输入内容时,它会进入 stdin 流和操作系统。而当您在终端中键入 "ls" 命令时,操作系统会将输出写入 stdout 流。stdout 流连接到您的显示器终端,因此您可以在那里看到输出结果。 - Tayyab
2
关于浏览器示例,浏览器不必保持文件打开。这取决于浏览器的实现方式,但在大多数情况下,浏览器会打开一个临时文件,写入文件,然后关闭文件,因此即使网页打开,也不必打开文件。描述符只是保存文件信息,并不一定将文件保存在RAM中。当您从描述符读取数据时,操作系统会从硬盘中读取数据。文件描述符中的信息仅表示硬盘上文件的位置等信息。 - Tayyab
7
文件描述符与文件之间不是一对一的映射。我可以通过多次调用 open() 来获得 4 个不同的文件描述符,每个文件描述符根据传递给 open() 的标志可以用于读取、写入或同时读写相应的文件。至于文件是存在 RAM 还是磁盘上这一点,由内核和它的各种缓存隐藏起来。最终,缓存中的数据将与磁盘上的数据匹配(在写入时),如果数据已经在缓存中,则内核不会再回到磁盘中进行读取。 - Beano
10
这是一篇易于理解的好文章 https://www.bottomupcs.com/file_descriptors.xhtml - Krishan Gopal
显示剩余6条评论
13个回答

5
除了以上所有简化的回答之外,如果您正在使用 bash 脚本处理文件,则最好使用文件描述符。
例如: 如果您想要从/向文件 "test.txt" 读取和写入,请使用下面所示的文件描述符:
FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor

# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor

为什么我们可以直接将文件传递到 while 循环中,而不需要使用 FD? - SaGeSpidy
1
exec 5<>$FILE 这段代码中的 <> 是什么意思?在其他教程中我只看到了 <,但是我认为使用 <> 可以防止文件创建,这似乎更好,但不确定它在这里具体做了什么。 - Joseph Astrahan

5

文件描述符就是打开任何资源的引用。当您打开资源时,内核假定您将对其执行某些操作。程序和资源之间的所有通信都通过接口进行,并且此接口由文件描述符提供。

由于进程可以打开多个资源,因此资源可能具有多个文件描述符。
您可以通过运行以下命令查看与进程关联的所有文件描述符: ls -li /proc//fd/ 这里的pid是您的进程的进程ID。


由于一个进程可以打开多个资源,因此一个资源可能有多个文件描述符。这不是一个正确的因果关系句子... - Omer Dagan

0

虽然我不懂内核代码,但我想分享我的看法,因为我已经思考了一段时间,我认为这会很有用。

当你打开一个文件时,内核会返回一个文件描述符来与该文件交互。

文件描述符是你正在打开的文件的API实现。内核创建此文件描述符,将其存储在数组中,并将其提供给你。

这个API需要一个实现,允许你读写文件,例如。

现在,请再次思考我所说的话,记住一切都是文件——打印机、显示器、HTTP连接等等。

这是我在阅读https://www.bottomupcs.com/file_descriptors.xhtml后的总结。


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