计算目录中的大量文件(在Linux中)最快/最简单的方法是什么?

我有一些目录,大量的文件。 每次我试图访问它里面的文件列表时,我都无法做到这一点,或者有显着的延迟。 我试图在Linux命令行中使用ls命令,而我的托pipe服务提供商的web界面也没有帮助。

问题是,当我做ls时,甚至开始显示某些东西需要花费大量的时间。 因此, ls | wc -l ls | wc -l也无济于事。

经过一番研究,我想出了这个代码(在这个例子中,它计算了一些服务器上的新邮件数量):

 print sum([len(files) for (root, dirs, files) in walk('/home/myname/Maildir/new')]) 

上面的代码是用Python编写的。 我使用Python的命令行工具,它工作得很快(立即返回结果)。

我对以下问题的答案感兴趣:是否可以更快地计算目录中的文件(无子目录)? 什么是最快的方法来做到这一点?

    ls为每个文件做一个stat(2)调用。 其他工具,如find(1)和shell通配符扩展,可能会避免这个调用,只是readdir 。 一个可能工作的shell命令组合是find dir -maxdepth 1|wc -l ,但是它会很乐意列出目录本身,并且用任何一个换行符错误地记录任何文件名。

    从Python中,直接获取这些名字的方法是os.listdir(directory) 。 与os.walk和os.path.walk不同,它不需要递归,检查文件类型或进行更多的Python函数调用。

    附录:这似乎ls并不总是统计。 至少在我的GNU系统中,当没有请求进一步的信息(比如哪些名字是目录)时,它只能做一个getdent调用。 getdents是用于在GNU / Linux中实现readdir的底层系统调用。

    加2:ls输出结果之前延迟的一个原因是它排序和制表。 ls -U1可以避免这个。

    在Python中这应该是相当快的:

     from os import listdir from os.path import isfile, join directory = '/home/myname/Maildir/new' print sum(1 for entry in listdir(directory) if isfile(join(directory,entry))) 

    给定目录中的文件总数

     find . -maxdepth 1 -type f | wc -l 

    给定目录及其下的所有子目录中的文件总数

     find . -type f | wc -l 

    欲了解更多详情,请进入终端,并man find

    我认为ls在显示第一行之前花费了大部分时间,因为它必须对条目进行排序,所以ls -U应该更快地显示第一行(虽然总体上可能不会那么好)。

    最快的方法是避免解释型语言的所有开销,并编写一些直接解决问题的代码。 这样做很难以便携的方式做,但非常简单。 目前我在OS X机器上,但将以下内容转换为Linux应该非常简单。 (我选择忽略隐藏的文件,只计算常规文件…根据需要修改或添加命令行开关,以获得您想要的功能。)

    
     #include <dirent.h>
     #include <stdio.h>
     #include <stdlib.h>
    
     INT
     main(int argc,char ** argv)
     {
         DIR * d;
         struct dirent * f;
         int count = 0;
         char * path = argv [1];
    
         if(path == NULL){
             fprintf(stderr,“usage:%s path”,argv [0]);
            退出(EXIT_FAILURE);
         }
         d = opendir(path);
         if(d == NULL){perror(path); exit(EXIT_FAILURE);  }
         while((f = readdir(d))!= NULL){
             if(f-> d_name [0]!='。'&& f-> d_type == DT_REG)
                 count + = 1;
         }
         printf(“%d \ n”,count);
        返回EXIT_SUCCESS;
     }
    
    

    我不知道速度,但如果你只想使用shell buildins这应该工作:

     #!/bin/sh COUNT=0; for file in /path/to/directory/* do COUNT=$(($COUNT+1)); done echo $COUNT 

    我的使用案例是一个Linux SBC(香蕉皮)计数在FAT32 USB棒的目录中的文件。 在一个外壳,做

     ls -U {dir} | wc -l 

    在这里有32个文件(32K =最大文件/ FAT32上的目录)6.4secs从python做

     t=time.time() ; print len(os.listdir(d)) ; print time.time()-t 

    只需要0.874secs(!)在Python中看不到任何东西比这更快。