I/O

binmode#

Ορίζει τη στοίβα στρωμάτων I/O σε ένα filehandle - τυπικά για να παραδίδει ωμά bytes ή για να επισυναφθεί μια κωδικοποίηση χαρακτήρων.

Η binmode αναδιαμορφώνει το FILEHANDLE έτσι ώστε οι επόμενες αναγνώσεις και εγγραφές να περνούν από μια συγκεκριμένη στοίβα στρωμάτων PerlIO. Στη μορφή με ένα όρισμα, θέτει το handle σε ωμή δυαδική κατάσταση (χωρίς μετατροπή CRLF, χωρίς αποκωδικοποίηση χαρακτήρων). Στη μορφή με δύο ορίσματα, ωθεί (ή, για μια χούφτα ψευδο-στρωμάτων, αντικαθιστά ή απομακρύνει) τα κατονομαζόμενα στρώματα I/O στη στοίβα του handle. Καλέστε την μετά την open και πριν από οποιοδήποτε I/O στο handle, εξαιρώντας το :encoding, που μπορεί να εφαρμοστεί στη μέση της ροής.

Σύνοψη#

binmode FILEHANDLE
binmode FILEHANDLE, LAYER

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

1 σε επιτυχία, undef σε αποτυχία, με την $! τεθειμένη. Η αποτυχία στην πράξη είναι σπάνια - η συνηθισμένη αιτία είναι η διαβίβαση κακοσχηματισμένης συμβολοσειράς στρώματος ή άγνωστου ονόματος στρώματος. Η τιμή επιστροφής αξίζει να ελέγχεται όταν το όρισμα του στρώματος παρέχεται από τον χρήστη:

binmode $fh, ":encoding($enc)"
    or die "bad encoding '$enc': $!";

Αν το FILEHANDLE είναι μια έκφραση αντί για bareword ή απλό βαθμωτό, η τιμή του λαμβάνεται ως το όνομα του filehandle, σύμφωνα με τους κανόνες ανάλυσης filehandle των open και print.

Καθολική κατάσταση που επηρεάζει#

Η ίδια η binmode δεν διαβάζει ειδικές μεταβλητές, αλλά τα στρώματα που εγκαθιστά αλλάζουν τον τρόπο με τον οποίο το μετέπειτα I/O στο handle αλληλεπιδρά με αυτές. Η στοίβα στρωμάτων καθορίζει πώς οι $/ (διαχωριστής εγγραφής εισόδου) και $\ (διαχωριστής εγγραφής εξόδου) αντιστοιχίζονται και εκπέμπονται έναντι της εξωτερικής ροής bytes - σε πλατφόρμες όπου η κατάσταση κειμένου μεταφράζει το \n σε ακολουθία πολλαπλών bytes, η μετατροπή συμβαίνει μέσα στο στρώμα, όχι στη μεταβλητή.

Στρώματα PerlIO#

Ένα στρώμα είναι μια συμβολοσειρά που ξεκινά με : και κατονομάζει ένα φίλτρο στη στοίβα PerlIO - δείτε το PerlIO για τον πλήρη κατάλογο. Μπορούν να δοθούν πολλαπλά στρώματα σε μία κλήση με συνένωσή τους:

binmode $fh, ":raw:utf8";

Η σειρά είναι από κάτω προς τα πάνω: το :raw εφαρμόζεται πρώτο (πλησιέστερα στον περιγραφέα αρχείου του OS), στη συνέχεια το :utf8 τοποθετείται πάνω από αυτό. Οι αναγνώσεις διασχίζουν τη στοίβα από κάτω προς τα πάνω· οι εγγραφές τη διασχίζουν από πάνω προς τα κάτω.

Τα συνήθως χρησιμοποιούμενα στρώματα:

  • :raw - γυμνώνει το handle σε byte-προς-byte I/O. Απενεργοποιεί τη μετατροπή CRLF, αφαιρεί τυχόν στρώματα κωδικοποίησης χαρακτήρων και σημαδεύει το handle ως bytes. Παρά τους περιστασιακούς ισχυρισμούς περί του αντιθέτου, το :raw δεν είναι απλά το αντίστροφο του :crlf· απενεργοποιεί επίσης οποιοδήποτε άλλο στρώμα που θα αλλοίωνε τη δυαδική φύση της ροής. Αυτό εγκαθιστά η μορφή με ένα όρισμα.

  • :crlf - μεταφράζει ακολουθίες \r\n σε \n στην είσοδο και \n σε \r\n στην έξοδο. Αυτή είναι η προεπιλογή σε συστήματα της οικογένειας Windows / DOS για handles σε κατάσταση κειμένου· η ρητή εφαρμογή του εξαναγκάζει τη μετατροπή CRLF σε οποιαδήποτε πλατφόρμα.

  • :utf8 - σημαδεύει τα δεδομένα του handle ως UTF-8. Χωρίς επικύρωση στην είσοδο: τα bytes γίνονται δεκτά και σημαδεύονται ως χαρακτήρες. Στην έξοδο, οι χαρακτήρες κωδικοποιούνται σε bytes UTF-8. Γρήγορο, αλλά εμπιστεύεται την πηγή.

  • :encoding(NAME) - αποκωδικοποιεί bytes σε χαρακτήρες στην είσοδο και κωδικοποιεί χαρακτήρες σε bytes στην έξοδο, χρησιμοποιώντας την κατονομαζόμενη κωδικοποίηση (UTF-8, iso-8859-1, shiftjis, κ.λπ.). Η μη έγκυρη για την κωδικοποίηση είσοδος προκαλεί προειδοποίηση και αντικατάσταση. Το :encoding ωθεί σιωπηρά το :utf8 πάνω από τον εαυτό του, διότι η Perl εργάζεται εσωτερικά σε UTF-8. Δείτε το PerlIO::encoding για λεπτομέρειες και επιλογές ρύθμισης.

  • :bytes - το αντίστροφο του :utf8· σημαδεύει τα δεδομένα του handle ως bytes, απενεργοποιώντας οποιαδήποτε σημαία χαρακτηριστικής σημασιολογίας έχει θέσει ένα υψηλότερο στρώμα.

Δύο ψευδο-στρώματα ελέγχουν το σχήμα της στοίβας αντί να φιλτράρουν:

  • :pop - αφαιρεί το πιο πάνω στρώμα από το handle.

  • :push - χρησιμοποιείται με το :via(...) για τη στοίβαξη ενός προσαρμοσμένου αρθρώματος στρώματος.

Το :raw στη μορφή με δύο ορίσματα λειτουργεί ως επαναφορά: αφαιρεί στρώματα μέχρι το handle να βρίσκεται στην πιο ελάχιστη κατάστασή του, αντί να ωθεί ένα νέο στρώμα από πάνω.

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

Η μορφή με ένα όρισμα, για φορητή ανάγνωση δυαδικού αρχείου:

open my $img, "<", "photo.jpg" or die $!;
binmode $img;
my $bytes = do { local $/; <$img> };

Ανάγνωση αρχείου κειμένου UTF-8 με επικύρωση:

open my $fh, "<", "notes.txt" or die $!;
binmode $fh, ":encoding(UTF-8)";
while (my $line = <$fh>) {
    # $line contains decoded characters, not bytes
}

Εγγραφή τερματισμών γραμμών τύπου Windows σε οποιαδήποτε πλατφόρμα:

open my $out, ">", "dos.txt" or die $!;
binmode $out, ":crlf";
print $out "one\ntwo\nthree\n";    # written as one\r\ntwo\r\nthree\r\n

Αφαίρεση προηγουμένως εφαρμοσμένου στρώματος κωδικοποίησης και επιστροφή σε bytes:

binmode $fh, ":pop";               # remove topmost layer
binmode $fh, ":raw";               # or: flatten to bare bytes

Επικύρωση κωδικοποίησης παρεχόμενης από τον χρήστη πριν τη δέσμευση σε αυτή:

my $enc = $ENV{INPUT_ENCODING} // "UTF-8";
binmode $fh, ":encoding($enc)"
    or die "unsupported encoding '$enc': $!";

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

  • Καλέστε την μετά την open, πριν από οποιοδήποτε I/O. Η binmode σε ένα handle από το οποίο έχει ήδη γίνει ανάγνωση ή εγγραφή παράγει ορισμένα αλλά εξαρτώμενα από την υλοποίηση αποτελέσματα· τα περισσότερα στρώματα εκκενώνουν τους εκκρεμείς ενταμιευτές κατά την εγκατάσταση, πράγμα που μπορεί να χάσει δεδομένα που πέρασαν τα όρια του στρώματος. Το :encoding αποτελεί την τεκμηριωμένη εξαίρεση - μπορεί να ωθηθεί στη μέση της ροής χωρίς εκκένωση.

  • Η μορφή με ένα όρισμα είναι :raw, όχι «δεν κάνει τίποτα». Σε Unix το παρατηρήσιμο αποτέλεσμα είναι συχνά μηδαμινό, διότι τα handles βρίσκονται ήδη σε κατάσταση προσανατολισμένη σε bytes, αλλά σε Windows απενεργοποιεί τη μετατροπή CRLF. Γράφετε φορητό κώδικα σαν η binmode $fh να είναι πάντα σημασιακά ενεργή.

  • CRLF σε Windows / DOS. Χωρίς binmode, το runtime της C σε αυτές τις πλατφόρμες μετατρέπει \r\n σε \n στην είσοδο και το αντίστροφο στην έξοδο. Για δυαδικές μορφές (εικόνες, συμπιεσμένα δεδομένα, σειριοποιημένες δομές) αυτό αλλοιώνει σιωπηλά τη ροή. Η binmode είναι εκεί υποχρεωτική.

  • Ctrl-Z ως τέλος αρχείου. Σε συστήματα της οικογένειας Microsoft, τα handles σε κατάσταση κειμένου αντιμετωπίζουν το \cZ (byte 0x1A) ως τέλος αρχείου. Δυαδικά δεδομένα που τυχαίνει να περιέχουν αυτό το byte θα εμφανιστούν αποκομμένα εκτός αν χρησιμοποιηθεί η binmode.

  • Το :utf8 βασίζεται μόνο στην εμπιστοσύνη. Ένα handle εισόδου με :utf8 αλλά χωρίς :encoding(UTF-8) θα σας παραδώσει ευχαρίστως μη έγκυρο UTF-8 σημαδεμένο ως χαρακτήρες. Χρησιμοποιήστε :encoding(UTF-8) όταν η πηγή δεν είναι έμπιστη.

  • Το :encoding παρασύρει το :utf8. Μετά από binmode $fh, ":encoding(shiftjis)" το handle έχει στη στοίβα του τόσο το :encoding(shiftjis) όσο και το :utf8 - η εσωτερική μορφή της perl είναι UTF-8 ανεξάρτητα από την κωδικοποίηση επί της γραμμής.

  • Εκφράσεις filehandle. Το binmode $handles[0], ":utf8" λειτουργεί· κάθε έκφραση που αποδίδει τιμή filehandle γίνεται δεκτή ως πρώτο όρισμα και αποτιμάται για να κατονομάσει το handle.

  • Επηρεάζει κάθε πρωτογενή λειτουργία I/O στο handle. Η στοίβα στρωμάτων διέπει εξίσου τις read, sysread, syswrite, seek, tell, print και readline. Συγκεκριμένα, η sysread και η syswrite σε ένα handle σημαδεμένο με :utf8 συνεχίζουν να περνούν από το στρώμα και ενδέχεται να επιστρέψουν μερικούς χαρακτήρες.

  • Αλληλεπίδραση με την pragma open. Το use open ":encoding(UTF-8)" εγκαθιστά ένα προεπιλεγμένο σύνολο στρωμάτων για τα handles που ανοίγουν μετέπειτα. Ρητή κλήση της binmode υπερισχύει της προεπιλογής αυτής για το συγκεκριμένο handle.

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

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

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

  • open - δημιουργεί εξαρχής το filehandle· δέχεται στρώματα απευθείας στη συμβολοσειρά κατάστασης (<:encoding(UTF-8)) ώστε να παρακαμφθεί μια επακόλουθη κλήση binmode

  • Encode - κωδικοποιεί και αποκωδικοποιεί συμβολοσειρές στη μνήμη, ανεξάρτητα από οποιοδήποτε filehandle

  • PerlIO - πλήρης κατάλογος στρωμάτων, συμπεριλαμβανομένων λιγότερο συνηθισμένων στρωμάτων όπως :scalar, :via και :mmap

  • read / sysread - πρωτογενείς λειτουργίες εισόδου των οποίων η σημασιολογία byte / χαρακτήρα εξαρτάται από τη στοίβα στρωμάτων

  • print / syswrite - πρωτογενείς λειτουργίες εξόδου των οποίων η κωδικοποίηση και η συμπεριφορά τερματισμού γραμμής εξαρτώνται από τη στοίβα στρωμάτων

  • $/ - διαχωριστής εγγραφής εισόδου, αντιστοιχιζόμενος έναντι της ροής bytes μετά τα στρώματα

  • $\ - διαχωριστής εγγραφής εξόδου, εγγραφόμενος μέσω της στοίβας στρωμάτων