我需要删除给定文件夹下的所有内容(文件和文件夹).问题是文件夹里面有数百万个文件和文件夹.所以我不想一次性加载所有文件名.
逻辑应该是这样的:
>迭代文件夹而不加载所有内容
>获取文件或文件夹
>删除它
(详细说明文件或文件夹“X”已删除)
>转到下一个
我正在尝试这样的事情:
sub main(){ my ($rc,$help,$debug,$root) = (); $rc = GetOptions ( "HELP" => \$help,"DEBUG" => \$debug,"ROOT=s" => \$root); die "Bad command line options\n$usage\n" unless ($rc); if ($help) { print $usage; exit (0); } if ($debug) { warn "\nProceeding to execution with following parameters: \n"; warn "===============================================================\n"; warn "ROOT = $root\n"; } # write debug information to STDERR print "\n Starting to delete...\n"; die "usage: $0 dir ..\n" unless $root; *name = *File::Find::name; find \&verbose,@ARGV; } sub verbose { if (!-l && -d _) { print "rmdir $name\n"; } else { print "unlink $name\n"; } } main();
它工作正常,但每当“find”读取巨大的文件夹时,应用程序就会卡住,我可以看到Perl的系统内存一直在增加,直到超时.为什么?它是否试图一次性加载所有文件?
谢谢你的帮助.
解决方法
perlfaq指出File :: Find完成了遍历目录的艰苦工作,但工作并不那么难(假设您的目录树没有命名管道,块设备等):
sub traverse_directory { my $dir = shift; opendir my $dh,$dir; while (my $file = readdir($dh)) { next if $file eq "." || $file eq ".."; if (-d "$dir/$file") { &traverse_directory("$dir/$file"); } elsif (-f "$dir/$file") { # $dir/$file is a regular file # Do something with it,for example: print "Removing $dir/$file\n"; unlink "$dir/$file" or warn "unlink $dir/$file Failed: $!\n"; } else { warn "$dir/$file is not a directory or regular file. Ignoring ...\n"; } } closedir $dh; # $dir might be empty at this point. If you want to delete it: if (rmdir $dir) { print "Removed $dir/\n"; } else { warn "rmdir $dir Failed: $!\n"; } }
用您自己的代码替换文件或(可能)空目录,并在要处理的树的根上调用此函数一次.查看opendir / closedir,readdir,-d和-f的含义,如果之前没有遇到过它们的话.