列出 AIX 机器上大目录中的文件
Posted
技术标签:
【中文标题】列出 AIX 机器上大目录中的文件【英文标题】:List files from a large directory on AIX machine 【发布时间】:2018-08-31 06:15:11 【问题描述】:我有一个包含大约 300 万个文件的目录。每天一次,我需要运行一个进程来创建一个单独的文件,该文件包含来自具有.html
扩展名的大目录中的文件名。通常,在 300 万个文件中,有 500,000 个将具有 .html
扩展名。我正在使用以下内容:
find dirname -name "*.html"
但是,这会在完成之前运行大约 3 小时。有没有更快的方法来做到这一点?
更新:我用 Perl 和 Java 做了一些测试。使用 Perl 获取此目录的内容并创建 .html
的文件我尝试了以下(注意时间):
my @files = </$dirname/*.html> # 45 minutes
当我使用 Java 尝试此操作时:
final File[] files = dirname.listFiles(new FilenameFilter()
@Override
public boolean accept(File dir, String name)
return name.endsWith(".html");
);
与 Perl 或我能想到的任何 Unix 命令相比,Java 是如何在 3 分钟内完成这项工作的?
【问题讨论】:
此目录中包含的文件非常小。每个文件平均 400k。ls
和 find
会因为文件数量而达到缓冲区限制,并且需要进行多次调用。您可以使用更大的缓冲区编写自己的ls
版本。
我将如何编写自己的 ls?
看起来你已经用 Java 写过一篇了!
你应该引用更多的代码。例如find directory -name '*.html' -exec echo \; >>listfile
比find directory -name '*.html' >listfile
慢
【参考方案1】:
默认文件glob()对文件列表进行排序;这就是为什么它需要很长时间。
my @files = </$dirname/*.html> # 45 minutes
尝试直接读取目录:
my @files = ();
opendir my $dh, $dirname or die "could not open $dirname: $!\n";
while( my $file = readdir $dh )
push @files, $file if $file =~ /\.html$/;
closedir $dh or die "could not close $dirname: $!\n";
【讨论】:
【参考方案2】:您应该使用“getdents”代替 ls/find
ls 和几乎所有其他列出目录的方法(包括 python os.listdir、find .)都依赖于 libc readdir()。但是 readdir() 一次只能读取 32K 的目录条目,这意味着如果您在同一个目录中有很多文件(即 500M 的目录条目),则读取所有目录条目将花费非常长的时间,尤其是在慢速磁盘上。对于包含大量文件的目录,您需要比依赖 readdir() 的工具更深入地挖掘。您需要直接使用 getdents() 系统调用,而不是 libc 中的辅助方法。
您可以从here 找到使用 getdents() 列出文件的 C 代码:
为了快速列出目录中的所有文件,您需要进行两项修改。
首先,将缓冲区大小从 X 增加到 5 兆字节。
#define BUF_SIZE 1024*1024*5
然后修改主循环,它打印出目录中每个文件的信息以跳过 inode == 0 的条目。我通过添加来做到这一点
if (dp->d_ino != 0) printf(...);
在我的例子中,我也只关心目录中的文件名,所以我还重写了 printf() 语句,只打印文件名。
if(d->d_ino) printf("%sn ", (char *) d->d_name);
编译它(它不需要任何外部库,所以超级简单)
gcc listdir.c -o listdir
现在运行
./listdir [directory with insane number of files]
【讨论】:
感谢 nakulbansal!但是您提供给 getdents 的链接不可用。 @PeteY 嗯?该链接非常适合我。这是一个以listdir.c
代码为例的手册页。顺便说一句,这与我在命令行上发出 man getdents
时得到的输出相同。【参考方案3】:
你可以像下面这样使用 ls
\ls -U
-U 不排序;按目录顺序列出条目
【讨论】:
以上是关于列出 AIX 机器上大目录中的文件的主要内容,如果未能解决你的问题,请参考以下文章