2015-05-06 3 views
3

На данный момент я знаю два способа открыть и прочитать каталог на Perl. Вы можете использовать opendir, readdir и closedir или можете просто использовать glob, чтобы получить содержимое каталога.Perl readdir как однострочный?


Пример:

Используя opendir, readdir и closedir:

opendir my $dh, $directory; 
my @contents = readdir $dh; 
closedir $dh; 

glob Использование:

my @contents = <$directory/*>; 

Я был проинформирован, что в некоторых ситуациях метод glob может привести к непредсказуемым результатам (например, он может действовать по-разному на разных операционных системах, когда он встречает специальные символы в именах каталогов).

Что мне нравится в методе glob, так это то, как «быстро и грязно». Это одна простая строка, и она выполняет свою работу, но если она не работает во всех ситуациях, которые могут привести к неожиданным и трудным для поиска ошибкам.

мне было интересно, если есть своего рода путь «сокращенном», чтобы использовать opendir, readdir, closedir метод?

Возможно, что-то вроде этого fancy method for slurping a file в одной строке, которую я недавно обнаружил.

+0

Мне любопытно, что думает тот, кто сообщил вам, что произойдет в тех случаях со специальными символами в именах каталогов. –

+0

@AndyLester Я думаю, что OP ссылается на комментарий о пробелах в именах каталогов. 'mkdir" foo bar "&& touch" foo bar/baz "&& perl -E '$ dir =" foo bar "; скажем, для <$dir/*> ''(можно решить, указав аргумент' glob') – ThisSuitIsBlackNot

+0

Вот отличная запись glob vs. readdir: https://stackoverflow.com/questions/1506801/what-reasons-are-there -to-prefer-glob-over-readdir-or-vice-versa-in-perl –

ответ

0

Я считаю, что я пришел с действительным однострочником, который включает opendir/readdir!

my @contents = do { opendir my $dh, $dir or die $!; readdir $dh }; 

Это должно открыть и прочитать каталог, вернуть все его содержимое и как только do блок концов, то $dh должен быть закрыт Perl «автомагически».

+0

Как это существенно отличается от 'opendir my $ dh, $ dir; my @contents = readdir $ dh; '? Вам не нужно 'do', чтобы поместить несколько операторов в одну строку. – ThisSuitIsBlackNot

+1

'do {}' делает локальную область my ($ dh) локально, так что дескриптор файла будет закрыт, как только он выйдет из области видимости.Это также позволяет объявлению 'my @ contents' быть вне этой области, поэтому оно может быть объявлено в одной строке и по-прежнему использоваться не локально. Если вы попытались локально охватить его без 'do {}', вы получите '{opendir my $ dh, $ dir; my @contents = readdir $ dh; } ', но тогда вы столкнулись с проблемой неспособности использовать' @ contents' на следующей строке, потому что теперь она будет недоступна! ... Его довольно красивая и изящная на самом деле. Перл потрясающий. ':)' – tjwrona1992

+0

Невозможно закрыть дескриптор лексической директории [редко бывает значительным] (http://stackoverflow.com/questions/3687198/what-are-the-implications-of-not-closing-a-directory-handle- in-perl), поэтому я не думаю, что то, что вы разместили, * существенно * отличается от простого ввода нескольких операторов в одной строке. Но так как вы уже знаете, что это плохая практика, я прекращу заниматься этим :) – ThisSuitIsBlackNot

2

Как насчет следующего?

my @contents = get_dir_contents($dir); 

Вы даже можете решить, как это обрабатывает ошибки, если . должны быть возвращены, если .. должны быть возвращены, если «скрытые» файлы должны быть возвращены и является ли путь перед именем файла, так как вы пишете get_dir_contents.


Альтернативы:

  • use File::Find::Rule qw(); 
    my @contents = File::Find::Rule->maxdepth(1)->in($dir); 
    
  • use File::Slurp qw(read_dir); 
    my @contents = read_dir($dir); 
    
  • # Unix only, but that includes cygwin and OS/X. 
    my @contents = <\Q$dir\E/.* \Q$dir\E/*>; 
    
+0

Мне нравится ['File :: Slurp :: read_dir'] (https://metacpan.org/pod/File::Slurp#read_dir), хотя я понимаю, что« File :: Slurp »в некоторых кругах выпадает из рук , –

+1

@Jim Davis, File :: Slurp раньше был багги, так что я всегда избегал этого. Я даже не знал, что у него такой подлог. Я понимаю, что эти проблемы были исправлены уже давно. Я добавил его к моему ответу. – ikegami

+0

@ikegami. Подпрограмма - это очевидное решение, это скорее теоретический вопрос. Я хочу, чтобы простейший самый простой способ чтения каталога. В основном это просто даст вам вывод по умолчанию 'readdir' без всякой неловкости наличия строки' opendir', чтобы получить дескриптор, за которым следует строка 'readdir', чтобы прочитать дескриптор, за которым следует строка' closedir', чтобы закройте ручку. – tjwrona1992

Смежные вопросы