我在AMD 64上使用Strawberry Perl并试图简单地读取包含数百万个文件的文件夹。这是一个NTFS驱动器。这段代码将运行几分钟,并且进程中的内存会一直增长,直到我最终得到“Out of Memory!”。关于为什么会出现内存的任何想法都会有所帮助,但我想知道这是否是一个真正的问题?
#!/usr/bin/perl
use strict;
my $dir = '../svcUploadedFiles';
my $file = '';
opendir(DIR, $dir) or die $!;
while ($file = readdir(DIR)) {
}
closedir(DIR);
exit 0;
答案 0 :(得分:1)
我怀疑这里的罪魁祸首是readdir
,但没有任何关于print
是否有任何区别的信息,我无法确定。
Perl必须支持rewwinddir
,telldir
和seekdir
以及简单的readdir
,因此我认为它将整个目录列表保留在内存中以方便这一点。
但是,我已经在一个包含6M文件的目录上运行你的代码,并且该进程的大小只有大约80MB,所以除非你的文件比这个文件多得多,否则它们的名字都比较长(这些都是大约12个字符) )然后我仍然无法解释这个问题。
解决问题的方法可能是从运行cmd.exe
命令的dir /b
进程打开管道。这将一次为您的主进程传递一个文件名,并且内存负载将在子进程上,因此不应该是一个问题。
<强>更新强>
好的,所以你的文件数量大约是我的两倍,所以让我们猜测160MB,这对于Perl进程来说应该不是问题。您的文件名称有多长,简化过程有多大?
这是一个Perl程序示例,它从dir
的输出中读取,而不是使用内部readdir
。它使Perl进程大约为3.6MB,rh cmd.exe
进程只有1MB以上。它比readdir
慢得多,但我无法想到另一种阅读和处理目录的方式,它应该是一个简单的替代品
use strict;
use warnings;
use 5.010;
use autodie;
my $dir = '../svcUploadedFiles';
open my $cmd_fh, '-|', qq{cmd /c dir /b "$dir"};
open my $file_fh, '>', 'filelist.txt';
while ( my $file = <$cmd_fh> ) {
chomp $file;
print $file_fh "$file\n";
}
close $file_fh;
close $cmd_fh;