Filehandles, αρχεία, κατάλογοι
opendir#
Ανοίγει έναν κατάλογο για ανάγνωση.
Η opendir συνδέει το DIRHANDLE με τον κατάλογο που υποδεικνύει το EXPR ώστε οι εγγραφές του καταλόγου να μπορούν να διαβαστούν με readdir και η θέση να χειριστεί με telldir, seekdir και rewinddir. Όταν τελειώσετε, η closedir απελευθερώνει το handle. Το DIRHANDLE ζει σε διαφορετικό χώρο ονομάτων από τα filehandles - ένα bareword που έχετε ήδη χρησιμοποιήσει με την open είναι ελεύθερο να επαναχρησιμοποιηθεί εδώ, και αντιστρόφως.
Σύνοψη#
opendir DIRHANDLE, EXPR
opendir my $dh, EXPR
Τι επιστρέφεται#
1 σε επιτυχία, 0 σε αποτυχία. Σε αποτυχία το $! κρατά τον λόγο - ο κατάλογος δεν υπάρχει, δεν είναι κατάλογος, δεν είναι αναγνώσιμος, ή η διεργασία έχει χτυπήσει το όριο ανοιχτών αρχείων. Ελέγχετε πάντα την επιστροφή· μια σιωπηλή αποτυχία εδώ μετατρέπεται σε μυστηριωδώς κενή readdir αργότερα.
opendir my $dh, $path
or die "opendir $path: $!";
Καθολική κατάσταση που επηρεάζει#
$!- τίθεται στη συμβολοσειρά σφάλματος του συστήματος σε αποτυχία, ανέπαφο σε επιτυχία. Αποτυπώστε το προτού κάποια άλλη κλήση συστήματος το αλλοιώσει.
Σημασιολογία handle#
Γίνονται δεκτές τρεις μορφές DIRHANDLE, και η επιλογή έχει σημασία:
Bareword - η
opendir DIR, $pathδημιουργεί ένα καθολικό σε επίπεδο πακέτου dirhandle με όνομαDIRστο τρέχον πακέτο. Παραμένει ανοιχτό μέχρι να καλέσετε ρητά τηνclosedirή να τερματιστεί το πρόγραμμα. Αποφύγετε σε νέο κώδικα· ο καθολικός χώρος ονομάτων μοιράζεται σε ολόκληρο το πακέτο.Μη ορισμένο βαθμωτό - η
opendir my $dh, $pathαυτο-δημιουργεί το$dhως αναφορά σε ένα φρέσκο ανώνυμο dirhandle. Όταν το$dhβγει από την εμβέλεια και το refcount του πέσει στο μηδέν, το handle κλείνει αυτόματα. Αυτή είναι η μορφή που πρέπει να χρησιμοποιείτε.Έκφραση - οποιαδήποτε έκφραση η τιμή της οποίας είναι χρήσιμη ως έμμεσο dirhandle (τυπικά ένα πραγματικό όνομα dirhandle που κρατείται σε μεταβλητή). Η ταυτότητα του handle προέρχεται από την τιμή της έκφρασης, όχι από τη συντακτική της μορφή.
Τα dirhandles και τα filehandles μοιράζονται το ίδιο υποκείμενο αντικείμενο I/O: ένα δεδομένο αντικείμενο μπορεί να είναι ανοιχτό ως το ένα ή το άλλο τη φορά, ποτέ και τα δύο. Το πέρασμα dirhandle στη read ή filehandle στη readdir είναι σφάλμα χρήσης, όχι σιωπηλή ανάγνωση μηδέν bytes.
Παραδείγματα#
Το κανονικό ιδίωμα opendir / readdir / closedir:
opendir my $dh, $dir
or die "opendir $dir: $!";
while (my $entry = readdir $dh) {
next if $entry eq '.' or $entry eq '..';
print "$dir/$entry\n";
}
closedir $dh;
Ανάγνωση κάθε εγγραφής σε λίστα με μία κίνηση. Η readdir σε περιβάλλον λίστας επιστρέφει όλες τις υπόλοιπες εγγραφές:
opendir my $dh, '.' or die "opendir .: $!";
my @entries = grep { !/^\.\.?\z/ } readdir $dh;
closedir $dh;
Βασιστείτε στη λεξιλογική εμβέλεια για τον καθαρισμό - δεν χρειάζεται ρητή closedir:
sub list_dir {
my ($path) = @_;
opendir my $dh, $path or return;
return grep { !/^\.\.?\z/ } readdir $dh;
# $dh goes out of scope here, handle is closed
}
Χειρισμός ενός καταλόγου που λείπει ή είναι μη αναγνώσιμος χωρίς θάνατο:
if (opendir my $dh, $path) {
while (defined(my $e = readdir $dh)) { ... }
closedir $dh;
} else {
warn "skipping $path: $!";
}
Επανάληψη από την αρχή ενός καταλόγου με rewinddir αντί για επανάνοιγμα:
opendir my $dh, $dir or die $!;
my @first_pass = readdir $dh;
rewinddir $dh;
my @second_pass = readdir $dh;
closedir $dh;
Οριακές περιπτώσεις#
Η αποτυχία θέτει το
$!, όχι το$@. Ηopendirαναφέρει μέσω του$!όπως και η υπόλοιπη οικογένεια I/O· το$@παραμένει ανέπαφο.Επαναχρησιμοποίηση ανοιχτού dirhandle. Η
opendirσε handle που είναι ήδη ανοιχτό κλείνει σιωπηλά τον παλιό κατάλογο πριν ανοίξει τον νέο. Προτιμήστε ρητήclosedirόταν ο κώδικας προορίζεται να είναι ευανάγνωστος.Σχετικές διαδρομές. Το
EXPRαναλύεται ως προς τον τρέχοντα κατάλογο εργασίας τη στιγμή της κλήσης. Αν κάνετεchdirαργότερα, μια σχετική διαδρομή που αποτυπώσατε νωρίτερα ενδέχεται να μη σημαίνει πια το ίδιο - το ήδη ανοιγμένο dirhandle εξακολουθεί να δείχνει στο σωστό inode ανεξαρτήτως.Symlinks. Η
opendirακολουθεί symlinks εξ ορισμού: το άνοιγμα ενός link προς κατάλογο ανοίγει τον στόχο. Οι εγγραφές που επιστρέφει ηreaddirείναι οι εγγραφές του στόχου, όχι του link.Διάρκεια ζωής bareword έναντι λεξιλογικής. Ένα bareword dirhandle είναι καθολικό και ζει περισσότερο από το περικλείον μπλοκ· ένα λεξιλογικό
my $dhκαθαρίζεται όταν τελειώνει η εμβέλεια. Η ακούσια ανάμειξη των δύο (opendir DH, $pathμέσα σε sub) διαρρέει dirhandles σε επαναλαμβανόμενες κλήσεις.Σύγχυση file vs dir handle. Δεν μπορείτε να κάνετε
printσε dirhandle ούτεreaddirαπό filehandle. Το σφάλμα αναδύεται στη μετέπειτα κλήση, όχι στηνopendir.globέναντιopendir. Ηglobεπεκτείνει μοτίβα τύπου κελύφους και επιστρέφει διαδρομές· ηopendirαπαριθμεί ακατέργαστες εγγραφές καταλόγου (συμπεριλαμβανομένων των.και..) χωρίς ερμηνεία. Χρησιμοποιήστεglobόταν θέλετε αντιστοίχιση μοτίβων· χρησιμοποιήστεopendirόταν θέλετε κάθε εγγραφή ακριβώς όπως την αποθηκεύει το σύστημα αρχείων.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
readdir- διαβάζει την επόμενη εγγραφή (ή όλες τις υπόλοιπες εγγραφές) από dirhandle που άνοιξε μεopendirclosedir- απελευθερώνει ένα dirhandle· σιωπηρή όταν ένα λεξιλογικό$dhβγαίνει από την εμβέλειαrewinddir- επαναφέρει τη θέση ανάγνωσης στην αρχή χωρίς επανάνοιγμαseekdir- επανατοποθετεί το dirhandle σε ένα σύμβολο που επέστρεψε προηγουμένως ηtelldirtelldir- τρέχουσα θέση ανάγνωσης ως αδιαφανές σύμβολο κατάλληλο γιαseekdirglob- εναλλακτική βασισμένη σε μοτίβα όταν θέλετε επέκταση ονομάτων αρχείων τύπου κελύφους αντί για ακατέργαστη απαρίθμηση καταλόγου