2009-06-25 20 views

risposta

65

Se si desidera ottenere il contenuto di una data directory, e solo esso (cioè senza sottodirectory), il modo migliore è quello di utilizzare opendir/readdir/closedir:

opendir my $dir, "/some/path" or die "Cannot open directory: $!"; 
my @files = readdir $dir; 
closedir $dir; 

È anche possibile utilizzare:

my @files = glob($dir . '/*'); 

Ma a mio parere non è buono, soprattutto perché glob è una cosa abbastanza complessa (può filtrare i risultati automaticamente) e usarlo per ottenere tutti gli elementi di directory sembra un compito troppo semplice.

D'altra parte, se avete bisogno di ottenere contenuti da tutte le directory e sottodirectory, non v'è praticamente una soluzione standard:

use File::Find; 

my @content; 
find(\&wanted, '/some/path'); 
do_something_with(@content); 

exit; 

sub wanted { 
    push @content, $File::Find::name; 
    return; 
} 
+0

Ho sempre dimenticato che readdir restituisce solo una lista di nomi di file relativi, non l'intero percorso! –

+0

Grazie per aver scoraggiato l'uso del globbing per questo compito. Un altro svantaggio dell'uso del globbing per questo è che non troverà i file nascosti (quelli che iniziano con un punto). – josch

9

questo dovrebbe farlo.

my $dir = "bla/bla/upload"; 
opendir DIR,$dir; 
my @dir = readdir(DIR); 
close DIR; 
foreach(@dir){ 
    if (-f $dir . "/" . $_){ 
     print $_," : file\n"; 
    }elsif(-d $dir . "/" . $_){ 
     print $_," : folder\n"; 
    }else{ 
     print $_," : other\n"; 
    } 
} 
+1

si dovrebbe verificare opendir per il fallimento (opendir ... o morire "Messaggio di errore : $! "). Inoltre, mi manca qualcosa? Cosa sta facendo Win32 :: GUI :: DoEvents()? (Non vedo nulla di rilevante nella domanda.) – Telemachus

+0

questo è il modo migliore che non voglio o desidero ricordare espressioni regolari per qualcosa che dovrebbe essere facile da fare, userò questo per creare una funzione come lista ($ dir , "f"); per i file "d" per la directory, grazie per aver postato questo – Geomorillo

11

O File::Find

use File::Find; 
finddepth(\&wanted, '/some/path/to/dir'); 
sub wanted { print }; 

Sarà passare attraverso le sottodirectory se esistono.

2

Questo elenco di tutto (compresi gli indici secondari) dalla directory specificare, in ordine e con gli attributi. Ho passato giorni a cercare qualcosa per farlo, e ho preso parte da questa discussione intera, e un po 'di mia, e ho messo insieme. GODERE!!

#!/usr/bin/perl -- 
print qq~Content-type: text/html\n\n~; 
print qq~<font face="arial" size="2">~; 

use File::Find; 

# find(\&wanted_tom, '/home/thomas/public_html'); # if you want just one website, uncomment this, and comment out the next line 
find(\&wanted_tom, '/home'); 
exit; 

sub wanted_tom { 
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat ($_); 
$mode = (stat($_))[2]; 
$mode = substr(sprintf("%03lo", $mode), -3); 

if (-d $File::Find::name) { 
print "<br><b>--DIR $File::Find::name --ATTR:$mode</b><br>"; 
} else { 
print "$File::Find::name --ATTR:$mode<br>"; 
} 
    return; 
} 
+3

Arghh, i miei occhi! – javs

3

Se sei un fannullone come me come si potrebbe utilizzare il modulo File::Slurp. La funzione read_dir volontà legge il contenuto della directory in un array, elimina i puntini, e se il prefisso necessario i file restituiti con il dir per percorsi assoluti

my @paths = read_dir('/path/to/dir', prefix => 1) ; 
Problemi correlati