当使用POSIX/Unix系统(大数据)时,`ls-f | grep-c.`是计算目录中文件数的最快方法吗?
我过去常常使用当使用POSIX/Unix系统(大数据)时,`ls-f | grep-c.`是计算目录中文件数的最快方法吗?,unix,filesystems,bigdata,Unix,Filesystems,Bigdata,我过去常常使用ls路径访问任何| wc-l,直到我发现它实际上消耗了大量内存。然后我转到查找到which-name“*”| wc-l的路径,这似乎消耗了大量内存,而不管您有多少文件 然后我了解到,由于对结果进行排序,ls通常速度较慢,内存效率较低。使用ls-f | grep-c.,可以得到非常快的结果;唯一的问题是文件名中可能有“换行符”。然而,对于大多数用例来说,这是一个非常小的问题 这是计数文件的最快方法吗 编辑/可能的答案:似乎在大数据方面,有报道称ls、find等的某些版本挂起了超过80
ls路径访问任何| wc-l
,直到我发现它实际上消耗了大量内存。然后我转到查找到which-name“*”| wc-l
的路径,这似乎消耗了大量内存,而不管您有多少文件
然后我了解到,由于对结果进行排序,ls通常速度较慢,内存效率较低。使用ls-f | grep-c.
,可以得到非常快的结果;唯一的问题是文件名中可能有“换行符”。然而,对于大多数用例来说,这是一个非常小的问题
这是计数文件的最快方法吗
编辑/可能的答案:似乎在大数据方面,有报道称ls、find等的某些版本挂起了超过800万个文件(不过需要确认)。为了成功地处理非常大的文件计数(我猜>22亿),应该使用getdents64系统调用,而不是getdents,这可以通过支持POSIX标准的大多数编程语言来完成。一些文件系统可能提供更快的非POSIX方法来计算文件。一种方法是使用
readdir
并计算条目(在一个目录中)。下面我计算常规文件的数量,并使用d_type==DT_REG
,该文件可用于有限的OSs和FSs(man readdir
,请参见注释),但您可以只注释掉该行并计算所有dir条目:
#include <stdio.h>
#include <dirent.h>
int main (int argc, char *argv[]) {
struct dirent *entry;
DIR *dirp;
long long c; // 64 bit
if(argc<=1) // require dir
return 1;
dirp = opendir (argv[1]);
if (dirp == NULL) { // dir not found
return 2;
}
while ((entry = readdir(dirp)) != NULL) {
if(entry->d_type==DT_REG)
c++;
// printf ("%s\n", entry->d_name); // for outputing filenames
}
printf ("%lli\n", c);
closedir (dirp);
return 0;
}
(我需要打扫我的房间)
编辑:
我将1000000个文件放入一个目录中,并运行一个快速比较(显示了5个最佳用户+系统):
编辑2:
按照评论中的要求:
$ time ./a.out testdir | wc -l
1000004
real 0m0.567s
user 0m0.124s
sys 0m0.468s
计算目录中的文件数,非递归?大约,我们在谈论多少个文件?可能是@James Brown的复制品:我们在谈论数百万或数十亿个文件;实际上,人们对不同方案的理论计算复杂性更感兴趣。我还对文件系统/操作系统级别的答案感兴趣,而不仅仅是“完成任务”ls-U1似乎是一个非常好的选择。但是,它不是POSIX标准;不过,我对Unix解决方案很满意。编辑了这个问题,因为我已经找到了令人满意的答案;然而,我仍然对这个问题的理论方面感兴趣。非常感谢你的回答!您是否也可以运行一个与ls-f(启用文本输出和
time../a.out | wc-l
)相同的测试,以便这两种方法在功能上相同?添加了结果。Ole hyvä。
$ time ls -f | grep -c .
1000005
real 0m1.771s
user 0m0.656s
sys 0m1.244s
$ time ls -f | wc -l
1000005
real 0m1.733s
user 0m0.520s
sys 0m1.248s
$ time ../a.out .
1000003
real 0m0.474s
user 0m0.048s
sys 0m0.424s
$ time ./a.out testdir | wc -l
1000004
real 0m0.567s
user 0m0.124s
sys 0m0.468s