And*_*niz 4 perl file-handling
我需要删除给定文件夹下的所有内容(文件和文件夹).问题是文件夹里面有数百万个文件和文件夹.所以我不想一次性加载所有文件名.
逻辑应该是这样的:
我正在尝试这样的事情:
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();
Run Code Online (Sandbox Code Playgroud)
它工作正常,但每当"find"读取巨大的文件夹时,应用程序就会卡住,我可以看到Perl的系统内存一直在增加,直到超时.为什么?它是否试图一次性加载所有文件?
谢谢你的帮助.
File :: Path中的remove_tree函数可以移植和详细地删除目录层次结构,如果需要,保留顶层目录.
use strict;
use warnings;
use File::Path qw(remove_tree);
my $dir = '/tmp/dir';
remove_tree($dir, {verbose => 1, keep_root => 1});
Run Code Online (Sandbox Code Playgroud)
在5.10之前,使用File :: Path中的rmtree函数.如果你仍然想要顶级目录,你可以再次mkdir它.
use File::Path;
my $dir = '/tmp/dir';
rmtree($dir, 1); # 1 means verbose
mkdir $dir;
Run Code Online (Sandbox Code Playgroud)
该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";
}
}
Run Code Online (Sandbox Code Playgroud)
用您自己的代码替换文件或(可能)空目录,并在要处理的树的根上调用此函数一次.查找的含义opendir/closedir,readdir,-d,并且-f如果你还没有遇到过他们.