I/O

readdir#

Διαβάζει την επόμενη εγγραφή, ή όλες τις υπόλοιπες εγγραφές, από ένα handle καταλόγου που άνοιξε η opendir.

Η readdir είναι το αντίστοιχο για καταλόγους της readline: τραβά ονόματα από ένα handle καταλόγου ένα τη φορά σε βαθμωτό περιβάλλον, ή όλα μαζί σε περιβάλλον λίστας. Το handle πρέπει να έχει ήδη ανοιχτεί με opendir· η επανάληψη προχωρά μια θέση που οι rewinddir, seekdir και telldir μπορούν να χειριστούν.

Σύνοψη#

readdir DIRHANDLE
my $name  = readdir $dh;
my @names = readdir $dh;
while (readdir $dh) { ... }     # sets $_

Τι επιστρέφεται#

Εξαρτάται από το περιβάλλον:

  • Βαθμωτό περιβάλλον: το όνομα της επόμενης εγγραφής ως συμβολοσειρά, ή undef όταν εξαντληθεί ο κατάλογος.

  • Περιβάλλον λίστας: κάθε υπόλοιπη εγγραφή ως λίστα συμβολοσειρών, ή η κενή λίστα όταν ο κατάλογος είναι ήδη εξαντλημένος.

Οι εγγραφές είναι σκέτα ονόματα αρχείων, όχι διαδρομές. Η readdir επιστρέφει "foo.txt", ποτέ "/some/dir/foo.txt". Αν σκοπεύετε να παραδώσετε το αποτέλεσμα σε file test, open, stat, ή οποιαδήποτε άλλη κλήση που αναλύει διαδρομές ως προς τον τρέχοντα κατάλογο εργασίας, προσθέστε εσείς ως πρόθεμα τον κατάλογο - η readdir δεν κάνει chdir στον κατάλογο που διαβάζει.

Η λίστα περιλαμβάνει πάντα τις εγγραφές . (τρέχων κατάλογος) και .. (γονικός κατάλογος) όπως τις αναφέρει το υποκείμενο σύστημα αρχείων. Φιλτράρετέ τις ρητά αν δεν τις θέλετε:

my @real = grep { $_ ne '.' && $_ ne '..' } readdir $dh;

Η σειρά εξαρτάται από το σύστημα αρχείων, δεν είναι αλφαβητική. Τα ext4, XFS, tmpfs, NFS και FAT επιστρέφουν το καθένα εγγραφές στη δική του εσωτερική σειρά, η οποία μπορεί να είναι σειρά εισαγωγής, σειρά κατακερματισμού, ή κάτι εντελώς άλλο. Μην υποθέτετε ποτέ ταξινομημένη έξοδο. Αν χρειάζεστε προβλέψιμη σειρά, ταξινομήστε το αποτέλεσμα:

my @names = sort readdir $dh;

Παραδείγματα#

Διαβάστε κάθε όνομα σε λίστα, απορρίψτε τις εγγραφές με τελείες, και ταξινομήστε:

opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
my @names = sort grep { !/^\.\.?\z/ } readdir $dh;
closedir $dh;

Επανάληψη μία εγγραφή τη φορά. Μια σκέτη readdir σε συνθήκη while αναθέτει στο $_ και ελέγχει το αποτέλεσμα για ορισμένο, όχι για αλήθεια - οπότε μια εγγραφή με κυριολεκτικό όνομα "0" εξακολουθεί να κρατά τον βρόχο σε λειτουργία:

opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
while (readdir $dh) {
    print "$some_dir/$_\n";
}
closedir $dh;

File test με τον κατάλογο προθεμένο - η παράλειψη του προθέματος είναι το κλασικό σφάλμα της readdir:

opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
my @dotfiles = grep { /^\./ && -f "$some_dir/$_" } readdir $dh;
closedir $dh;

Βαθμωτό περιβάλλον - ένα όνομα ανά κλήση, το undef σηματοδοτεί τέλος καταλόγου:

opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
while (defined(my $name = readdir $dh)) {
    next if $name eq '.' || $name eq '..';
    process("$some_dir/$name");
}
closedir $dh;

Επαναφορά και ανάγνωση για δεύτερη φορά - το handle παραμένει ανοιχτό και χρήσιμο:

my @first  = readdir $dh;
rewinddir $dh;
my @second = readdir $dh;   # same entries, possibly different order

Οριακές περιπτώσεις#

  • Εξαντλημένο handle: περαιτέρω κλήσεις επιστρέφουν undef σε βαθμωτό περιβάλλον, κενή λίστα σε περιβάλλον λίστας. Χρησιμοποιήστε rewinddir για να ξεκινήσετε ξανά.

  • Κλειστό ή μη έγκυρο handle: επιστρέφει undef (βαθμωτό) ή κενή λίστα (λίστα) και θέτει το $!. Υπό use warnings η Perl εκπέμπει readdir() attempted on invalid dirhandle.

  • Έλεγχος ορισμένου σε while: τόσο το while (readdir $dh) όσο και το while (my $n = readdir $dh) (και τα αντίστοιχά τους για for) αντιμετωπίζονται ως ειδικές περιπτώσεις ώστε να ελέγχουν defined, όχι αλήθεια. Μια εγγραφή με όνομα "0" επιστρέφεται και ο βρόχος συνεχίζεται.

  • Τα . και .. είναι πάντα παρόντα σε συστήματα αρχείων POSIX, ακόμα και σε διαφορετικά κενό κατάλογο. Φιλτράρετέ τα αν θέλετε μόνο πραγματικό περιεχόμενο.

  • Κανένα πρόθεμα διαδρομής: οι εγγραφές είναι σκέτα ονόματα. Κάθε file test ή open πάνω στην ακατέργαστη τιμή επιστροφής ελέγχει σχετικά ως προς τον τρέχοντα κατάλογο εργασίας, όχι ως προς το $some_dir.

  • Καμία ταξινόμηση: η σειρά είναι όποια επιστρέφει ο πυρήνας. Εφαρμόστε ρητά sort αν η σταθερότητα έχει σημασία.

  • Ταυτόχρονες αλλαγές καταλόγου: εγγραφές που προστίθενται ή αφαιρούνται κατά την επανάληψη μπορεί να εμφανιστούν ή όχι, ανάλογα με την πλατφόρμα. Η μόνη ασφαλής υπόθεση είναι ότι εγγραφές που είναι παρούσες κατά τη στιγμή της opendir και δεν αφαιρέθηκαν θα αναφερθούν.

  • Κωδικοποίηση: η readdir επιστρέφει συμβολοσειρές bytes όπως τις αποθηκεύει ο πυρήνας. Σε σύστημα αρχείων που χρησιμοποιεί ονόματα αρχείων UTF-8, εφαρμόστε Encode::decode_utf8 ή ρυθμίστε το pragma open αν χρειάζεστε συμβολοσειρές χαρακτήρων.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • opendir - ανοίγει το handle καταλόγου από το οποίο διαβάζει η readdir· πάντα η πρώτη κλήση στην ακολουθία

  • closedir - απελευθερώνει το handle μόλις ολοκληρωθεί η επανάληψη

  • rewinddir - επαναφέρει τη θέση επανάληψης στην αρχή του καταλόγου

  • seekdir - μεταπηδά σε μια προηγουμένως καταγεγραμμένη θέση

  • telldir - καταγράφει την τρέχουσα θέση για μετέπειτα seekdir

  • glob - αντιστοίχιση μοτίβων τύπου κελύφους επί του περιεχομένου καταλόγου· υψηλότερου επιπέδου όταν θέλετε *.txt αντί για κάθε εγγραφή