【问题标题】:Does readdir() guarantee an order?readdir() 是否保证订单?
【发布时间】:2012-01-23 19:30:31
【问题描述】:

我正在使用 opendir/readdir 获取类 linux 系统上的文件列表。似乎目录条目是按文件名的字母顺序返回的。但是,我在手册页中没有看到任何关于保证此订单的内容。

谁能告诉我 readdir 是否保证订单?

【问题讨论】:

  • 根据经验,如果文档中没有,则答案是否定的。即使所有实现的顺序恰好一致,如果没有记录,也可能无法保证。
  • 如果它们是按字母顺序出现的,那几乎可以肯定它们最初是按字母顺序创建的,例如通过unziptar 提取它们...readdir 不提供任何顺序。
  • 顺便说一句,scandir 可能会在您想订购结果或随机访问它们时很有用。它在 POSIX 2008 中被标准化,在此之前是一个常见的扩展。
  • 你得到的排序几乎肯定取决于文件系统。在 FAT32 上,我按创建顺序获取文件,在 NTFS 上通常按字母顺序但有一些例外,在 ext4 上没有明显的顺序。你的保证订单就到这里了。 :)
  • 我什至见过“.”的情况。和“..”不是第一个条目(在网络安装的文件系统中)。当创建和删除混杂在一起时,我不会太指望创建顺序。

标签: c readdir


【解决方案1】:

readdir 方法不保证任何排序。如果您想确保它们按字母顺序排序,您需要自己这样做。

注意:我搜索了一些明确的文档,说是这种情况。我最接近的是以下链接

这绝不是确定性的,但它确实很好地概述了命令、它的历史以及它的实现通常是如何遍历顺序的。

【讨论】:

    【解决方案2】:

    简而言之,不,readdir() 不保证任何特定的顺序。

    来自glibc manual 中的 readdir 示例

    文件出现在目录中的顺序往往是公平的 随机的。一个更有用的程序会对条目进行排序(也许通过 在打印之前按字母顺序排列)

    【讨论】:

      【解决方案3】:

      来自“Linux 编程接口”:

      readdir() 返回的文件名不是按顺序排列的,而是按 它们碰巧在目录中出现的顺序(这取决于 文件系统将文件添加到目录中,以及在删除文件后如何填补目录列表中的空白)。 (ls –f 命令以与readdir() 检索相同的未排序顺序列出文件。)

      我们可以使用函数scandir(3) 来检索匹配的文件的排序列表 程序员定义的标准;有关详细信息,请参阅手册页。虽然不是 在 SUSv3 中指定,scandir() 在大多数 UNIX 实现中提供。

      注意:scandir 是 POSIX.1-2008 的一部分。在FreeBSD libc 中提供了围绕readdir 定义的许可版权版本。

      【讨论】:

        【解决方案4】:

        明确不保证。排序通常遵循一些规则,但规则足够复杂,您不应该依赖它们。例如,排序可能会受到同一目录中发生的其他操作的影响,而您无法控制这些操作。将排序视为随机排序,如果需要,请自行排序。

        【讨论】:

          【解决方案5】:

          不,readdir 不保证任何顺序。

          (某些文件系统可能会按特定顺序存储目录条目,在这种情况下 readdir 可能会以相同的顺序将它们返回给您,但这不是 readdir 本身的功能。)

          【讨论】:

            【解决方案6】:

            readdir() 不保证 OS 磁盘读取顺序之上的任何其他顺序。


            根据我在几个平台上进行的测试 - Solaris - sun4sol、x86 sol、linux、Windows 以及示例代码,所有结果都以随机方式显示。


            来源:readdir() beginning with dots instead of files

            #include <stdio.h>
            #include <stdlib.h>
            #include <dirent.h>
            
            int main() {
            
                DIR *dir;
                struct dirent *dp;
                char * file_name;
                char dirpath [100] ;
            
            
                while(1==1){
                    printf("Choose dir:");
                    scanf("%s",dirpath);
                    dir = opendir(dirpath);
                    while ((dp=readdir(dir)) != NULL) {
                        if ( !strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..") )
                        {
                            // do nothing (straight logic)
                        } else {
                            file_name = dp->d_name; // use it
                            printf("file_name: \"%s\"\n",file_name);
                        }
                    }
                    closedir(dir);
                }
            
                return 0;
            }
            

            【讨论】:

            • 只是为了好玩:while(1==1) 可以写成 while(1) 或简单的 for(;;)
            【解决方案7】:

            除了其他答案之外,readdir man page 对文件排序非常清楚。

            连续调用 readdir() 读取文件名的顺序取决于文件系统的实现;名称不太可能以任何方式排序。

            一些文件系统,如 ReiserFS 确实按词法顺序列出文件。

            在您的情况下,您必须将名称存储在数组中,然后对数组进行排序。

            例如,使用qsort() 对数组进行排序。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-07-26
              • 1970-01-01
              • 2020-01-22
              • 1970-01-01
              • 1970-01-01
              • 2020-05-25
              • 1970-01-01
              相关资源
              最近更新 更多