为什么目录列表包含当前 (.) 和父 (..) 目录?
每当我使用 readdir 这样的函数列出目录的内容时,返回的文件名也包含“.”。 和 ”..”。 我怀疑这些只是文件系统中的正常链接,因此与实际文件无法区分,但我总是必须将它们过滤掉,因为它们不是我列出的目录中的实际对象。 像 readdir 这样的函数有充分的理由包含它们吗? 某些操作系统或文件系统是否包含更多或不同的虚拟文件名? 除了与“.”进行字符串比较之外,还有更好的方法来过滤掉它们吗? 和 ”..”?
更新:谢谢大家的回答。 我想我一直认为像 ./ 和 ../ 这样的东西只是可以通过搜索和替换来处理的约定。 我觉得让它们成为文件系统本身的一部分有点令人惊讶,尽管可能更有效和透明。
但仍然存在一个问题:自从 . 和 .. 是这些链接的任意名称,是否存在使用不同名称的文件系统?
Whenever I list the contents of a directory with a function like readdir, the returned file names also include "." and "..". I have the suspicion that these are just normal links in the file system and therefore indistinguishable from actual files, but I always have to filter them out because they are not actual objects in the directory I am listing. Is there a good reason for functions like readdir to include them? Do some operating systems or file systems contain more or different virtual file names? Is there a better way to filter them out other than by doing string comparison with "." and ".."?
Update: thank you all for answering. I suppose I always thought that things like ./ and ../ were mere conventions that could be handled by searching and replacing. I find it a bit surprising, though probably more efficient and transparent, to have them be part of the file system itself.
One question remains, though: since . and .. are arbitrary names for these links, are there file systems that use different ones?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
.
和..
实际上是文件系统中的硬链接。 需要它们,以便您可以根据某些参考路径指定相对路径(考虑"../sibling/file.txt"
)。 由于这些硬链接实际上存在于文件系统中,因此readdir
告诉您它们是有意义的。 (实际上,术语硬链接
只是意味着一些与实际引用的目录无法区分的名称:它们都指向文件系统中相同的inode
)。如果您不想列出它们,最好的方法是仅使用
strcmp
并忽略它们。.
and..
are actually hard links in filesystems. They are needed so that you can specify relative paths, based on some reference path (consider"../sibling/file.txt"
). Since these hard links are actually existing in the filesystem, it makes sense forreaddir
to tell you about them. (actually the termhard link
just means some name that is indistinguishable from the actual directory referred to: they both point to the sameinode
in the filesystem).Best way is to just
strcmp
and ignore them, if you don't want to list them.最初它们是硬链接,以及 . 和..是最小的。 然而,并非所有现代文件系统都是如此。
但约定已经建立,因此即使这两个目录条目实际上不存在的文件系统仍然可以通过 readdir 等 API 报告它们的存在。 现在改变这个会破坏很多代码。
Originally they were hard links, and the number of special cases in the filesystem code for . and .. were minimal. That's not true for all modern filesystems, however.
But the conventions have been established so that even filesystems where these two directory entries don't actually exist still report their existence through APIs like readdir. Changing this would now would break a lot of code.
它们是。 虽然您可能将文件系统视为“文件夹”“包含”文件夹的层次结构,但它实际上是一个双向链接的树1,目录是节点,文件是叶子。 因此,
.
和..
是访问当前节点的叶子和遍历树所需的链接,它们与所有其他链接相同。当你调用
readdir
时,你会得到当前节点可以直接到达的所有地方。 如果您不想列出您认为“向上”的地方,则必须自己整理它们。 您应该为此编写一个小函数,也许称为readdir_down
。 我不知道 readdir 按什么顺序列出目录,但也许您可以丢弃前两个条目。1)这是第一个近似值,还有可能使树实际上成为一个网的“硬链接”。
They are. While you may perceive the file system as a hierarchy of "folders" "containing" folders, it is actually a doubly linked tree1, with directories being nodes and files being leafs. So,
.
and..
are needed links for accessing the leaves of the current node and for traversing the tree, and they are the same thing as all the other links.When you call
readdir
, you get all the places you can directly go to from the current node. If you do not want to list places that you perceive as "up", you have to sort them out yourself. You should write a little function for that, perhaps calledreaddir_down
. I do not know in which orderreaddir
lists the directories, but perhaps you can just throw away the first two entries.1) this is a first approximation, there are also "hard links" possible that make the tree actually a net.
原因之一是没有它们就无法访问父目录。 或者获取当前目录的句柄。
没有它们,我们就不能做这样的事情:
事实上,我们无法添加“.”。 到 $PATH,这意味着我们无法执行路径中尚未存在的文件。
One reason is that without them there is no way to get to the parent directory. Or get a handle to the current directory.
Without them, we cannot do such things as:
Indeed, we couldn't add '.' to the $PATH, meaning we couldn't ever execute files that weren't already in the path.
这些是普通目录,它们是当前目录和上面目录的“硬链接”。 它们存在于所有目录中(甚至在根级别,其中
..
与.
完全相同)。使用
ls
时,可以使用ls -A
过滤掉.
和..
(注意大写的-A
)。当将命令应用于所有点文件,但不应用于
.
或..
时,我经常使用.??*
,它仅匹配点-名称包含三个或更多字符的文件。请注意,此模式还排除以点开头且只有两个字符长的任何其他文件(例如
.x
),但这些文件并不常见。当使用像
readdir()
这样的编程文件列表器时,我必须手动排除.
和..
。 由于这两个文件应该位于 readdir() 返回的列表中的第一个文件,因此您可以这样做:These are normal directories, they are "hard links" to the current directory and directory above. They are present in all directories (even at the root level, where
..
is exactly the same as.
).When using
ls
, you can filter out.
and..
withls -A
(note the capital-A
).When applying a command to all dot-files, but not
.
or..
, I often use.??*
which matches only dot-file with a name of three characters or more.Note this pattern also excludes any other file that begins with dot and is only two characters long (e.g.
.x
) but those files are uncommon.When using programmatic file-listers like
readdir()
I do have to exclude.
and..
manually. Since these two files are supposed to be first in the list returned byreaddir()
you can do this:它们被报告是因为它们存储在目录列表中。 这就是 unice 一直以来的工作方式。
They are reported because they are stored in the directory listing. That's the way unices have always worked.
因为在类 Unix 操作系统上,目录列表命令包含这些命令,并且您可以使用它们在文件系统层次结构中上下移动。
像
grep { not /^.{1,2}\z/ } readdir HANDLE
之类的东西应该适合你。Because on Unix-like operating systems, the directory-listing commands include those, and you use them to move up and down in the filesystem hierarchy.
Something like
grep { not /^.{1,2}\z/ } readdir HANDLE
should work for you.目录扫描没有充分理由返回这些文件名。
there is no good reason a directory scan should return these filenames.