我正在寻找一种快速查找 Linux 目录中文件数量的方法。
任何在目录中的文件数量上花费线性时间的解决方案都是不可接受的(例如“ls | wc -l”和类似的东西),因为它会花费非常长的时间(有数千万甚至数亿目录中的文件)。
我确定目录中的文件数量必须作为一个简单的数字存储在文件系统结构中的某个地方(也许是 inode?),作为用于存储目录条目的数据结构的一部分 - 我怎样才能得到这个数字?
编辑:文件系统是 ext3。如果没有可移植的方式来做这件事,我愿意做一些特定于 ext3 的事情。
我正在寻找一种快速查找 Linux 目录中文件数量的方法。
任何在目录中的文件数量上花费线性时间的解决方案都是不可接受的(例如“ls | wc -l”和类似的东西),因为它会花费非常长的时间(有数千万甚至数亿目录中的文件)。
我确定目录中的文件数量必须作为一个简单的数字存储在文件系统结构中的某个地方(也许是 inode?),作为用于存储目录条目的数据结构的一部分 - 我怎样才能得到这个数字?
编辑:文件系统是 ext3。如果没有可移植的方式来做这件事,我愿意做一些特定于 ext3 的事情。
为什么数据结构要包含数字?一棵树不需要知道它在 O(1) 中的大小,除非它是一个要求(并且提供它,可能需要更多的锁定并且可能是性能瓶颈)
我所说的树并不是指包含子目录内容,而是包含 -maxdepth 1 的文件——假设它们没有真正存储为列表..
编辑:ext2 将它们存储为链表。
现代 ext3 实现散列 B 树
话虽如此,/bin/ls 的作用远不止计数,而且实际上会扫描所有 inode。使用 opendir() 和 readdir() 编写您自己的 C 程序或脚本。
从这里:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main()
{
int count;
struct DIR *d;
if( (d = opendir(".")) != NULL)
{
for(count = 0; readdir(d) != NULL; count++);
closedir(d);
}
printf("\n %d", count);
return 0;
}
您可以使用 inotify 跟踪和记录受监视目录中的文件创建和取消链接事件。它将分配维护文件计数所需的总时间,并允许您立即检索当前文件计数。
目录的 inode 不存储其中的文件数,因为通常不需要将文件计数与目录中的名称列表分开。目录 inode 的链接计数确实间接给出了子目录的数量(st_nlink是子目录的数量加二)。
我认为您别无选择,只能通读目录中的整个文件列表。find 可能会也可能不会比 ls 快。
这是一个为什么大目录是一个问题的例子,即使目录是使用 B-tree 实现的。
没有便携的方法可以做到这一点。低级文件原语,即readdir,就像它是一个线性列表一样工作。显然,这是一种抽象,一些文件系统可能会存储一个计数。但是,访问它本质上是特定于文件系统的。
如果您愿意跳过障碍,您可能会将每个目录都放在不同的文件系统中,使用配额,并使用“repquota”命令获取信息。