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 που εγκαθίστανται από τη pragma open ή τον διακόπτη -CioD. Ισχύουν μόνο όταν το MODE στη μορφή τριών ορισμάτων δεν περιέχει ρητό στρώμα· ένα γυμνό < ή > τα τιμά, ενώ ένα <:raw ή οποιοδήποτε άλλο ρητό στρώμα τα καταστέλλει.

  • $^F - ο υψηλότερος περιγραφέας αρχείου που δεν έχει σημανθεί ως close-on-exec· ο νέος fd κληρονομεί τη σημαία close-on-exec βάσει αυτού.

  • Το επιλεγμένο filehandle μέσω της select - δεν τροποποιείται από την open, αλλά γίνεται σχετικό τη στιγμή που κάνετε print στο νέο handle χωρίς να το ονομάσετε.

  • Για τις μορφές σωλήνωσης, τα $? και ${^CHILD_ERROR_NATIVE} ορίζονται όταν αργότερα κλείσει το handle.

Τρόποι (modes)#

Το δεύτερο όρισμα ονομάζει έναν ρόλο I/O. Οι συνηθισμένες περιπτώσεις:

Τρόπος (mode)

Σημασία

ισοδύναμο της fopen(3)

<

ανάγνωση

r

>

εγγραφή, αποκοπή ή δημιουργία

w

>>

προσάρτηση, δημιουργία αν λείπει

a

+<

ανάγνωση και εγγραφή, χωρίς αποκοπή

r+

+>

ανάγνωση και εγγραφή, αποκοπή πρώτα

w+

|-

σωλήνωση προς εντολή (γράφουμε)

-

-|

σωλήνωση από εντολή (διαβάζουμε)

-

<&, >&, <&=, >&=

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}: οποιοδήποτε ρητό στρώμα, ακόμη και η :, απενεργοποιεί τις προεπιλογές της pragma open. Αν βασίζεστε σε προεπιλογή της 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 σε ήδη ανοιχτό handle

  • read - αναγνώσεις σταθερού μεγέθους byte από το handle που επέστρεψε η open

  • readline - αναγνώσεις μία εγγραφή τη φορά (αυτό που καλεί το <$fh>)

  • fileno - ο υποκείμενος περιγραφέας αρχείου του ΛΣ, για flock, select ή fcntl

  • $! - σφάλμα ΛΣ που ορίζεται όταν η open επιστρέφει undef