我想知道文件描述符和文件名之间有什么区别和关系。它们都是用来访问文件的吗?如果是的话,同样的方式吗?
例如,/dev/fd/0
、/dev/stdin
、 和/proc/self/fd/0
都是指向 的链接/dev/pts/2
。这四个是文件描述符,还是文件名?
答案1
/dev/fd/0
、/dev/stdin
、/proc/self/fd/0
和全部四个/dev/pts/2
都是文件名,/////dev/../dev/fd//0
、/bin/sh
、/etc/fstab
、/fioejfoeijf
等也是如此。除了最后一个示例之外,所有其他示例都可能是计算机上现有文件的名称。文件名是一个字符串,可以指定文件系统上的文件;在 Linux 下,任何不包含空字节且长度最多为 4096 字节的字符串都是有效的文件名。其中许多名称是等效的,例如/bin/sh
相当于///bin/sh
, /bin/../bin/sh
(假设/bin
是现有目录)等。到目前为止我给出的所有示例都是绝对文件名;还有相对文件名,它们不以 a 开头/
,其含义取决于当前目录。
文件名相关的术语并不通用;有时“文件名”表示文件的完整路径,有时表示目录条目的名称。 POSIX 术语是“文件名“ 或者 ”路径名组件” 作为目录条目的名称,以及“路径名” 以获得完整路径。
文件描述符指定一个打开特定进程中的文件。内核为每个进程维护一个文件描述符表。文件描述符表中的每个条目指示如果进程请求对文件描述符进行读、写和其他操作时要执行的操作。
文件描述符可能对应于一个文件并具有关联的名称,但并非所有文件描述符都如此。对于那些这样做的人来说,该文件可能是常规文件、目录、设备文件或命名管道(也称为 FIFO)(创建的那种mkfifo
);有些系统还有更多的可能性,例如 Unix 套接字和门。没有关联命名文件的文件描述符的示例包括管道(由创建的那种pipe
系统调用)和网络插座。
/dev/fd/0
、/dev/stdin
和/proc/self/fd/0
是具有特殊含义的文件名(全部等效):它们都指定当前通过文件描述符 0 访问的文件。当进程打开这些文件时,内核会将文件描述符表中索引为 0 的条目复制到新描述符。打开这些文件中的任何一个都相当于调用dup(0)
。命名文件是一种间接让进程使用其已打开的文件而不是打开新文件的方法;它们对于传递程序的命令行最有用,程序需要在命令行中打开文件的名称。
答案2
文件名只是文件系统上文件的名称,仅此而已 - 它只是一个字符串。
文件描述符是某种对象,您可以从中读取和/或写入。这是打开并准备好的文件。不仅有文件描述符 - stdin、stdout 和 stderr 也是描述符,您可以使用与文件完全相同的功能对它们进行写入和读取(除非您不能进行查找)。非文件描述符的其他示例包括:命名管道和网络套接字。
在代码中,文件描述符是一个变量,指向内核中的某个东西的指针,它代表文件对象。
例如,/dev/fd/0、/dev/stdin、/proc/self/fd/0 都是指向 /dev/pts/2 的链接。这四个是文件描述符,还是文件名?
这些都是伪文件,对某些脚本或程序很有用。您可以打开它们,并且 open() 会返回一个文件描述符。