Filehandles, αρχεία, κατάλογοι
open#
Συσχετίζει ένα filehandle με ένα αρχείο, μια εντολή ή ένα βαθμωτό στη μνήμη.
Η open είναι ο κύριος τρόπος με τον οποίο ένα πρόγραμμα Perl αποκτά ένα filehandle. Η μορφή τριών ορισμάτων - open $fh, MODE, EXPR - είναι αυτή που πρέπει να χρησιμοποιείτε σε νέο κώδικα: ο τρόπος (mode) δηλώνεται ρητά, το όνομα αρχείου δεν μπορεί να επανερμηνευτεί ως σωλήνωση κελύφους, και οι λευκοί χαρακτήρες στην αρχή ή το τέλος του EXPR διατηρούνται κατά λέξη. Η παλαιότερη μορφή δύο ορισμάτων υπάρχει για συμβατότητα και για τη «μαγική» ερμηνεία ονόματος αρχείου που επιτρέπει· μην της δίνετε μη έμπιστη είσοδο.
Σύνοψη#
open my $fh, "<", $path or die "read $path: $!";
open my $fh, ">", $path or die "write $path: $!";
open my $fh, ">>", $path or die "append $path: $!";
open my $fh, "+<", $path or die "rw $path: $!";
open my $fh, "<:encoding(UTF-8)", $path or die $!;
open my $mem, ">", \$buf or die $!; # in-memory
open my $pipe, "-|", "ls", "-la" or die $!; # read from cmd
open my $pipe, "|-", "gzip", ">$f" or die $!; # write to cmd
Τι επιστρέφεται#
1 σε επιτυχία· undef σε αποτυχία, με το $! ορισμένο στο σφάλμα του ΛΣ. Για τις μορφές με σωλήνα (|- / -|), η επιτυχημένη τιμή επιστροφής είναι το pid της θυγατρικής διεργασίας - χρήσιμο όταν χρειάζεται να εφαρμόσετε αργότερα waitpid. Μετά από άνοιγμα σωλήνα ενός ή δύο ορισμάτων με την κυριολεκτική εντολή -, η open επιστρέφει δύο φορές (ο γονέας λαμβάνει το pid του παιδιού, το παιδί λαμβάνει 0)· χρησιμοποιήστε defined($pid) ή // για να τα διακρίνετε.
Ελέγχετε πάντα την τιμή επιστροφής. Μια αποτυχημένη open αφήνει το filehandle κλειστό, και κάθε επόμενη ανάγνωση ή εγγραφή σε αυτό θα ορίσει το $! σε Bad file descriptor και θα εκπέμψει προειδοποίηση υπό use warnings.
open my $fh, "<", $path
or die "open $path: $!";
Καθολική κατάσταση που επηρεάζει#
$!- ορίζεται σε αποτυχία στο σφάλμα σε επίπεδο ΛΣ.${^OPEN}- προεπιλεγμένα στρώματα I/O που εγκαθίστανται από τη pragmaopenή τον διακόπτη-CioD. Ισχύουν μόνο όταν τοMODEστη μορφή τριών ορισμάτων δεν περιέχει ρητό στρώμα· ένα γυμνό<ή>τα τιμά, ενώ ένα<:rawή οποιοδήποτε άλλο ρητό στρώμα τα καταστέλλει.$^F- ο υψηλότερος περιγραφέας αρχείου που δεν έχει σημανθεί ως close-on-exec· ο νέος fd κληρονομεί τη σημαία close-on-exec βάσει αυτού.Το επιλεγμένο filehandle μέσω της
select- δεν τροποποιείται από τηνopen, αλλά γίνεται σχετικό τη στιγμή που κάνετεprintστο νέο handle χωρίς να το ονομάσετε.Για τις μορφές σωλήνωσης, τα
$?και${^CHILD_ERROR_NATIVE}ορίζονται όταν αργότερα κλείσει το handle.
Τρόποι (modes)#
Το δεύτερο όρισμα ονομάζει έναν ρόλο I/O. Οι συνηθισμένες περιπτώσεις:
Τρόπος (mode) | Σημασία | ισοδύναμο της |
|---|---|---|
| ανάγνωση |
|
| εγγραφή, αποκοπή ή δημιουργία |
|
| προσάρτηση, δημιουργία αν λείπει |
|
| ανάγνωση και εγγραφή, χωρίς αποκοπή |
|
| ανάγνωση και εγγραφή, αποκοπή πρώτα |
|
| σωλήνωση προς εντολή (γράφουμε) | - |
| σωλήνωση από εντολή (διαβάζουμε) | - |
| dup ή fdopen ενός υπάρχοντος handle | - |
Τα νεοδημιουργηθέντα αρχεία λαμβάνουν δικαιώματα 0666 & ~umask. Το +< είναι σχεδόν πάντοτε αυτό που θέλετε για ανάγνωση-εγγραφή· το +> πρώτα αδειάζει το αρχείο.
Τα στρώματα I/O προσαρτώνται μετά τον τρόπο: <:encoding(UTF-8), >:raw, >>:crlf, <:encoding(UTF-8):crlf. Ένα ρητό στρώμα καταστέλλει τις προεπιλογές του ${^OPEN}· μία μόνη άνω-κάτω τελεία (<:) επανέρχεται στην προεπιλογή του ΛΣ (:raw σε Unix, :crlf σε Windows).
Παραδείγματα#
Διαβάστε ένα αρχείο κειμένου UTF-8 γραμμή προς γραμμή:
open my $fh, "<:encoding(UTF-8)", "notes.txt"
or die "open notes.txt: $!";
while (my $line = <$fh>) {
chomp $line;
# ... use $line ...
}
close $fh or warn "close: $!";
Γράψτε ένα δυαδικό αρχείο χωρίς μετάφραση κωδικοποίησης:
open my $out, ">:raw", "image.bin"
or die "open image.bin: $!";
print $out $bytes;
close $out or die "close: $!";
Filehandle στη μνήμη - print μέσα σε βαθμωτό, χρήσιμο για τη σύλληψη εξόδου που αναμένει πραγματικό handle:
my $buf = "";
open my $mem, ">", \$buf or die $!;
print $mem "hello\n";
close $mem;
# $buf now contains "hello\n"
Ανάγνωση από εντολή, μορφή λίστας ώστε τα ορίσματα να μην υπόκεινται σε ερμηνεία μετα-χαρακτήρων κελύφους:
open my $ls, "-|", "ls", "-la", $dir
or die "ls: $!";
while (<$ls>) { print }
close $ls; # $? holds the exit status
Προσωρινό ανώνυμο αρχείο - περάστε undef ως τρίτο όρισμα με τρόπο ανάγνωσης-εγγραφής, και κατόπιν εφαρμόστε seek πίσω στην αρχή για να διαβάσετε όσα γράψατε:
open my $tmp, "+>", undef or die $!;
print $tmp "scratch data\n";
seek $tmp, 0, 0;
my $line = <$tmp>;
Οριακές περιπτώσεις#
«Μαγικό» άνοιγμα δύο ορισμάτων: η
open $fh, $nameτιμά τα προπορευόμενα<,>,>>, ένα τελικό|, και αφαιρεί τους περιβάλλοντες λευκούς χαρακτήρες από το$name. Μια χαρά για κυριολεκτικό όνομα αρχείου που πληκτρολογήσατε ο ίδιος· ποτέ για όνομα αρχείου που προήλθε από είσοδο χρήστη, από το δίκτυο ή από μεταβλητή περιβάλλοντος. Χρησιμοποιήστε τη μορφή τριών ορισμάτων.Δύο ορίσματα με
-: ηopen $fh, "<-"ήopen $fh, "-"ανοίγει τοSTDIN· ηopen $fh, ">-"ανοίγει τοSTDOUT. Τα ισοδύναμα τριών ορισμάτων είναιopen $fh, "<", "-"καιopen $fh, ">", "-".Επανάνοιγμα των
STDOUT/STDERR: κλείστε τα πρώτα, και μετά ξανανοίξτε τα προς τον νέο στόχο. Ηopen STDOUT, ">", \$bufανακατευθύνει κάθε μετέπειτα έξοδοprint STDOUTστο$buf.Bareword filehandles (
open FH, ...) είναι καθολικά πακέτου και απενεργοποιούνται υπόuse v5.36ή νεότερο μέσω του χαρακτηριστικούbareword_filehandles. Προτιμήστε ένα λεξιλογικό βαθμωτό.Στρώματα και
${^OPEN}: οποιοδήποτε ρητό στρώμα, ακόμη και η:, απενεργοποιεί τις προεπιλογές της pragmaopen. Αν βασίζεστε σε προεπιλογή της pragma, παραλείψτε εντελώς την άνω-κάτω τελεία (<, όχι<:).Σωλήνωση σε εντολή με μετα-χαρακτήρες κελύφους: η μορφή σωλήνωσης δύο ορισμάτων (
open $fh, "|cat -n | lpr") εκτελείται μέσω/bin/sh -c. Η μορφή λίστας τριών ορισμάτων (open $fh, "|-", "cat", "-n") όχι, και είναι η ασφαλέστερη προεπιλογή.Βαθμωτές συμβολοσειρές στη μνήμη: αντιμετωπίζονται ως συμβολοσειρές οκταδικών. Χωρίς αποκοπή, το βαθμωτό δεν επιτρέπεται να περιέχει σημεία κώδικα πάνω από το
0xFF.Αυτόματο κλείσιμο κατά την έξοδο εμβέλειας: ένα λεξιλογικό filehandle κλείνει όταν ο μετρητής αναφορών του φτάσει στο μηδέν, αλλά το έμμεσο κλείσιμο δεν αναφέρει σφάλματα. Για αρχεία στα οποία γράψατε, κλείστε τα ρητά και ελέγξτε την τιμή επιστροφής.
Η
openέναντι τηςsysopen: ηopenπεριτυλίγει τη σημασιολογία τηςfopen(3)με στρώματα PerlIO από πάνω. Για άμεσες σημαίες τηςopen(2)όπωςO_EXCLήO_NOFOLLOW, χρησιμοποιήστε τηνsysopen.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
close- απελευθερώστε ένα filehandle· ελέγξτε την τιμή επιστροφής για εγγραφές με buffer και εντολές σωλήνωσηςsysopen- άνοιγμα με ωμές σημαίες τηςopen(2)όταν χρειάζεστεO_EXCL,O_NOFOLLOWή ανάλογη ακρίβειαbinmode- τοποθετήστε ή αντικαταστήστε στρώματα I/O σε ήδη ανοιχτό handleread- αναγνώσεις σταθερού μεγέθους byte από το handle που επέστρεψε ηopenreadline- αναγνώσεις μία εγγραφή τη φορά (αυτό που καλεί το<$fh>)fileno- ο υποκείμενος περιγραφέας αρχείου του ΛΣ, γιαflock,selectήfcntl