目录如何是“特殊文件类型”?


Answers:


19

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

定义* nix上下文中“文件”是什么的一种方法是,它是与文件描述符关联的东西。根据维基百科的文章,文件描述符

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

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

从这种意义上讲,目录有点特殊,因为在本机C代码中,目录从表面上看与文件描述符不相关。POSIX API使用一种特殊类型的流句柄DIR*。但是,实际上,此类型确实具有可以检索的基础描述符。描述符由内核管理,访问它们始终涉及系统调用,因此,描述符的另一方面是它是由OS内核控制的管道。它们具有以0开头的唯一(每个进程)数字,该数字通常是标准输入流的描述符 。


2
POSIX.1-2008添加了许多系统调用(openatfstatat等),这些调用使用引用目录的文件描述符。
zwol 2015年

2
更有趣的是,您可以创建fsync()一个只读(!)目录fd,并且具有明确定义的效果(具体地说,它将给定目录中的文件创建/重命名/删除操作同步到磁盘,这是“写入”中理论上必需的步骤到一个临时文件,然后将其重命名为原始的“成语”)。
凯文(Kevin)

13

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

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

其他类型的特殊文件:

  • 链接
  • 插座
  • 设备

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


1
这使生活变得更加轻松,因为您不必仅因为它是目录而不必执行其他操作。这适用于编写程序以及通过命令行(或GUI)进行的操作。
gbarry

1
目录确实包含数据:描述目录中包含的文件的数据。完全可以访问目录(尽管可能不是通过标准的open调用)并自己读取该数据,但是(如Bruce Ediger在其回答中指出的那样),除非知道格式,否则数据的使用并不多。
jamesqf 2015年

11

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

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

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



1
今天,您仍然可以在某些Unix变体中打开目录并将其读取为文件,例如,在FreeBSD 10.1上仍然可以使用。(可以≠应该)
吉尔斯(Gills

@Gilles我认为如果dd复制的目录本质上等效于cp --link dir1/* dir2,这将是非常合乎逻辑的,尽管我不确定其可用性。
彼得说恢复莫妮卡

3

目录的特殊之处在于它的模式下带有'd',它告诉文件系统它应该将其内容解释为目录中包含的其他文件的列表,而不是将常规文件视为字节序列的文件。由应用程序读取。就这些。


对于所有文件系统来说,事情并不是那么简单-例如,如果我没记错的话,在Apple的HFS +中,只有一个大的B +树包含所有路径名-但是这种观察在Unix文件系统中一直存在,包括BSD的ffs,这可能是所引用教程的作者所想到的。
zwol 2015年

2

目录是文件,因为linux系统采用通用的I / O模型。在模型中,系统中的所有内容都是文件,可以使用相同的系统调用和各种命令进行访问。

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

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


-3

接受的答案并不完全正确。在POSIX系统中,“ Inodes”指向文件和目录。文件描述符仅是进程唯一的,并非整个系统唯一。索引节点是唯一的,尽管一个以上的索引节点可以指向一个文件。本可以对接受的答案发表评论,但由于答辩限制而无法发表评论。


2
不可以,只有1个inode可以指向同一文件。尽管同一索引节点可以同时存在于多个目录(或多个名称)中。简单检查:ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt。因此,您将看到,硬链接具有相同的inode编号。
彼得说恢复莫妮卡

@peterh文件描述符仅对进程唯一。你可以解释吗?
alamin

1
@ Md.AlaminMahamud这是不对的,如果一个进程fork()s,其子进程将具有(与某些特殊情况除外,即O_CLOEXEC标志)与原始进程完全相同的文件描述符实体。另一个示例:apache子进程listen()在同一个套接字文件描述符上运行。但是这个答案与文件描述符无关,文件描述符是内核内部的数据结构,仅存在于内核内存中。这个()答案是关于目录条目和索引节点的,它们是磁盘上的实体(即它们是硬盘驱动器上的物理字节)。
彼得说恢复莫妮卡

1
@ Md.AlaminMahamud好吧,现在我不太确定,例如,如果fork()发生子进程seek()或子进程close(),它不会影响父进程的文件描述符。所以我现在在想,文件描述符只是部分进程专用的结构。但是这个问题不是关于他们的,这个问题是关于地价/收益的,我正在就这个问题的完全错误的答案与您进行评论。
彼得说恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.