Обнаружение пустого каталога с помощью Perl
Что такое простой способ проверить, нет ли папки в perl? -s и -z не работают.
Пример:
#Ensure Apps directory exists on the test PC.
if ( ! -s $gAppsDir )
{
die "\n$gAppsDir is not accessible or does not exist.\n";
}
#Ensure Apps directory exists on the test PC.
if ( ! -z $gAppsDir )
{
die "\n$gAppsDir is not accessible or does not exist.\n";
}
Эти выше, не работают должным образом, чтобы сказать мне, что папка пуста. Спасибо!
Спасибо всем! Я закончил использование:
sub is_folder_empty { my $dirname = shift; opendir(my $dh, $dirname) or die "Not a directory";
return scalar(grep { $_ ne "." && $_ ne ".." } readdir($dh)) == 0; }
Ответы
Ответ 1
Немного подробный для ясности, но:
sub is_folder_empty {
my $dirname = shift;
opendir(my $dh, $dirname) or die "Not a directory";
return scalar(grep { $_ ne "." && $_ ne ".." } readdir($dh)) == 0;
}
Затем вы можете сделать:
if (is_folder_empty($your_dir)) {
....
}
Ответ 2
Использование grep { ! /^[.][.]?\z/ } readdir $dir_h
может быть проблематичным для производительности, если проверка выполняется много раз, а некоторые каталоги могут иметь много файлов.
Было бы лучше коротко замыкать момент, когда будет найден каталог, отличный от .
или ..
.
В Windows XP с ActiveState perl
5.10.1 следующая справка выглядит в два раза быстрее, чем метод grep
на моем $HOME
со 100 записями:
sub is_dir_empty {
my ($dir) = @_;
opendir my $h, $dir
or die "Cannot open directory: '$dir': $!";
while ( defined (my $entry = readdir $h) ) {
return unless $entry =~ /^[.][.]?\z/;
}
return 1;
}
Ответ 3
Существует также File::List
из cpan. Это слишком сложно, но может быть удобно для немного более сложных запросов, таких как тест, если каталог пуст, имея в виду, что он содержит только пустые каталоги (то есть: не файлы).
Ответ 4
opendir(DIR,"DIR PATH") or die "Unable to open directory \"DIR PATH\" \n";
my @drList = readdir(DIR);
close(DIR);
if( grep(/\w/,@drList) ){ print "Not Empty\n" }
else { print "Empty\n" }
Ответ 5
sub is_folder_empty {
my $dirname = shift;
my @files = File::Find::Rule->file()->name('*')->maxdepth(1)->in("$dirname");
return $#files < 0;
}
Ответ 6
Или без каких-либо grepping или регулярных выражений, что исключает возможность случайного получения странных имен файлов. Плюс чуть быстрее - это мое тестирование.
#!/usr/bin/perl
use strict;
use warnings;
sub is_dir_empty {
return -1 if not -e $_[0]; # does not exist
return -2 if not -d $_[0]; # in not a directory
opendir my $dir, $_[0] or # likely a permissions issue
die "Can't opendir '".$_[0]."', because: $!\n";
readdir $dir;
readdir $dir;
return 0 if( readdir $dir ); # 3rd times a charm
return 1;
}
my @folders = qw( ./ ./empty ./hasonefile ./hastwofiles ./doesnotexist ./afile );
for my $folder ( @folders ) {
print "Folder '$folder' ";
my $rc = is_dir_empty( $folder );
if( $rc == -1 ) {
print "does not exist\n";
} elsif( $rc == -2 ) {
print "is not a directory\n";
} elsif( !$rc ) {
print "is not empty\n";
} else {
print "is empty\n";
}
}
Довольно просто. Если вы получаете три действительных ответа от вызова readdir, то вы знаете, что там должен быть файл. Независимо от того, какое имя может иметь файл, или порядка, в котором файлы обрабатываются. Вы бы предпочли что-то, называемое "is_dir_used", поскольку мне лично не нравится двойное отрицательное имя функции и возвращаемое значение.
Ответ 7
Кредит DevShed
if (scalar <directory/*>) {print qq|File Exists\n|}
Изменить
Чтобы включить скрытые файлы:
@arr = <directory/* directory/.*>;
@arr = grep {!/^directory/[.]{1,2}$/} @arr;
if (@arr) { print qq|File or Directory Exists\n| }
Прочтите комментарии, поскольку были сделаны хорошие моменты. Несмотря на отрицательные моменты, полученные этим ответом, они все еще верны.