10

每当我使用 readdir 之类的函数列出目录的内容时,返回的文件名也包括“。” 和 ”..”。我怀疑这些只是文件系统中的普通链接,因此与实际文件无法区分,但我总是必须将它们过滤掉,因为它们不是我列出的目录中的实际对象。像 readdir 这样的函数是否有充分的理由包含它们?某些操作系统或文件系统是否包含更多或不同的虚拟文件名?除了与“。”进行字符串比较之外,还有更好的方法来过滤掉它们吗?和 ”..”?

更新:谢谢大家的回答。我想我一直认为像 ./ 和 ../ 这样的东西只是可以通过搜索和替换来处理的约定。我觉得让它们成为文件系统本身的一部分有点令人惊讶,尽管可能更有效和透明。

不过,一个问题仍然存在:因为 . 和 .. 是这些链接的任意名称,是否存在使用不同名称的文件系统?

4

8 回答 8

14

.并且..实际上是文件系统中的硬链接。它们是必需的,以便您可以根据一些参考路径指定相对路径(考虑"../sibling/file.txt")。readdir由于这些硬链接实际上存在于文件系统中,因此告诉您它们是有意义的。(实际上,该术语hard link仅表示与所引用的实际目录无法区分的某个名称:它们都指向inode文件系统中的同一个)。

strcmp如果您不想列出它们,最好的方法是忽略它们。

于 2008-11-27T01:49:28.303 回答
7

最初它们是硬链接,以及文件系统代码中特殊情况的数量。和..是最小的。然而,对于所有现代文件系统来说,情况并非如此。

但是已经建立了约定,因此即使这两个目录条目实际上不存在的文件系统仍然可以通过 readdir 之类的 API 报告它们的存在。现在改变它会破坏很多代码。

于 2008-11-27T03:10:41.947 回答
4

我怀疑这些只是文件系统中的正常链接,因此与实际文件无法区分

他们是。虽然您可能将文件系统视为“文件夹”“包含”文件夹的层次结构,但它实际上是一个双向链接树1,目录是节点,文件是叶子。因此,...是访问当前节点的叶子和遍历树所需的链接,它们与所有其他链接相同。

当你调用 时readdir,你会得到所有你可以从当前节点直接去的地方。如果您不想列出您认为“向上”的地方,则必须自己整理它们。您应该为此编写一个小函数,也许称为readdir_down. 我不知道以哪个顺序readdir列出目录,但也许您可以丢弃前两个条目。

1)这是第一个近似值,也有可能使树实际上成为网络的“硬链接”。

于 2008-11-27T02:10:26.577 回答
3

原因之一是没有它们就无法访问父目录。或者获取当前目录的句柄。

没有它们,我们就无法做以下事情:

./run_this

确实,我们无法添加“。” 到 $PATH,这意味着我们永远无法执行不在路径中的文件。

于 2008-11-27T01:45:43.147 回答
2

这些是普通目录,它们是指向当前目录和上面目录的“硬链接”。它们存在于所有目录中(即使在根级别,..与 完全相同.)。

使用 时ls,可以过滤掉...with ls -A(注意大写-A)。

将命令应用于所有点文件时,而不是.or ..,我经常使用.??*which 只匹配名称为三个或更多字符的点文件。

touch .??*

请注意,此模式还排除了任何其他以点开头且只有两个字符长(例如.x)的文件,但这些文件并不常见。

当使用像readdir()我这样的程序化文件列表时,必须.手动..排除。由于这两个文件应该是您返回的列表中的第一个文件,因此readdir()您可以这样做:

@files = readdir(DIR);
for (1..2) { shift @files; } # get rid of . and ..
# go on with your business
于 2008-11-27T01:47:00.087 回答
0

报告它们是因为它们存储在目录列表中。这就是 unices 一直以来的工作方式。

于 2008-11-27T01:47:36.327 回答
0

因为在类 Unix 操作系统上,目录列表命令包括这些命令,您可以使用它们在文件系统层次结构中上下移动。

类似的东西grep { not /^.{1,2}\z/ } readdir HANDLE应该适合你。

于 2008-11-27T01:50:37.800 回答
-4

目录扫描没有理由返回这些文件名。

于 2008-11-27T02:00:48.997 回答