目录如何成为“特殊类型的文件”?

目录如何成为“特殊类型的文件”?

我在读这个 Unix 教程并发现了这句话......

这里我们应该注意,目录只是一种特殊类型的文件。

...但没有提供任何解释或细节。为什么目录真的只是一个文件?

答案1

*nix 风格(和其他)操作系统中的许多实体都被视为文件,或者具有定义的类似文件的方面,即使它们不一定是存储在文件系统中的字节序列。目录的具体实现方式取决于文件系统的类型,但通常它们包含的内容(被视为列表)是存储字节的序列,因此从这个意义上说,它们并不那么特殊。

在 *nix 上下文中定义“文件”的一种方法是它是具有文件描述符与之相关。根据维基百科文章,文件描述符

是用于访问文件的抽象指示符或其他输入/输出资源,例如管道或网络连接...

换句话说,它们指的是可以读取/写入字节序列的各种资源,尽管该序列的源/目的地未指定。换句话说,资源的“位置”可以是任何东西。它的定义是它是信息的渠道。这就是为什么有时有人说在 UNIX 中“一切都是文件”的部分原因。你不应该完全从字面上理解这一点,但它值得认真考虑。对于目录,此信息与目录中的内容有关,并且在较低的实现级别上与如何在文件系统中找到它有关。

从这个意义上说,目录有点特殊,因为在本机 C 代码中,它们表面上并不与文件描述符相关联;而是与文件描述符相关联。 POSIX API 使用一种特殊类型的流句柄,DIR*.然而,这种类型实际上有一个底层描述符可以检索到。描述符由内核管理,访问它们总是涉及系统调用,因此描述符的另一个方面是它是由操作系统内核控制的管道。它们具有以 0 开头的唯一(每个进程)编号,这通常是该进程的描述符 标准输入溪流。

答案2

在 Unix 的做事方式中:一切都是文件。

目录是一种(多种)特殊文件类型。它不包含数据。相反,它包含指向目录中包含的所有文件的指针。

其他类型的特殊文件:

  • 链接
  • 插座
  • 设备

但因为它们被视为“文件”,所以您可以ls对它们进行重命名和移动,并根据特殊文件的类型,向它们发送数据或从它们发送数据。

答案3

我的回答只是回忆,但在 199x 的老式 Unix 中,有很多目录是文件,只是在磁盘 inode 的某处标记为“目录”。

您可以使用类似的方法打开一个目录open(".", O_RDONLY)并获取可用的文件描述符。如果您仔细查找/usr/include并找到正确的 C 结构体定义,则可以解析内容。我知道我是为 SunOS 4.1.x 系统、SGI 的 EFS 文件系统以及任何 DEC 的 Mips-CPU 工作站的文件系统(可能是 BSD4.2 FFS)执行此操作。

那是一次糟糕的经历。即使目录不再是严格的文件,虚拟文件​​系统层的标准化对于可移植性来说也是一件好事。 VFS 层让我们可以尝试目录不是文件的文件系统,例如 ReiserFS 或 NFS。

答案4

目录是文件,因为 Linux 系统使用通用输入/输出模型。在该模型中,系统中的所有内容都是文件,可以使用相同的系统调用和各种命令来访问它。

它们具有特殊类型,因为它们的索引节点具有文​​件类型的标记,并且它们具有作为文件名表和到其他索引节点的链接的特殊结构。这些文件名链接对(也称为“硬链接”)在目录的 i 节点中枚举目录“内部”的文件。

目录仅用于组织文件。当文件从一个目录“移动”到另一个目录时,文件本身不会在磁盘中重新定位。只是将一个目录 i-node 中的条目删除并写入另一个目录 i-node 中。

相关内容