I/O

readline#

Διαβάζει μία ή περισσότερες εγγραφές από ένα filehandle.

Η readline είναι το πρωτογενές στοιχείο εισόδου πίσω από τον τελεστή «διαμάντι» <FH>. Διαβάζει από το filehandle που ονομάζει το EXPR (typeglob, αναφορά glob ή IO::Handle), χρησιμοποιώντας την τρέχουσα τιμή της $/ για να αποφασίσει πού τελειώνει μία εγγραφή. Αν το EXPR παραλειφθεί, διαβάζεται το *ARGV. Σε βαθμωτό περιβάλλον επιστρέφει την επόμενη εγγραφή· σε περιβάλλον λίστας επιστρέφει κάθε υπολειπόμενη εγγραφή. Το τέλος αρχείου σηματοδοτείται με undef (βαθμωτό) ή με κενή λίστα.

Σύνοψη#

my $line  = readline $fh;       # one record, scalar context
my @all   = readline $fh;       # every remaining record
my $line  = <$fh>;              # same as scalar readline $fh
my @all   = <$fh>;              # same as list  readline $fh
readline;                       # reads from *ARGV

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

  • Βαθμωτό περιβάλλον: την επόμενη εγγραφή ως συμβολοσειρά, ή undef σε τέλος αρχείου ή σε σφάλμα. Η εγγραφή περιλαμβάνει τον τερματιστή της (την τρέχουσα $/) εκτός αν στην τελευταία εγγραφή του αρχείου λείπει. Μετά την επιστρεφόμενη τιμή, η $. αυξάνεται - δείτε την ενότητα για την καθολική κατάσταση παρακάτω.

  • Περιβάλλον λίστας: λίστα με κάθε υπολειπόμενη εγγραφή μέχρι το τέλος αρχείου. Κενή λίστα σημαίνει ότι το handle ήταν ήδη στο EOF.

  • Λειτουργία slurp σε κενό αρχείο: όταν η $/ είναι undef και το περιβάλλον βαθμωτό, η πρώτη κλήση σε handle μηδέν bytes επιστρέφει '' (κενή συμβολοσειρά, ορισμένη)· η επόμενη κλήση επιστρέφει undef. Αυτό επιτρέπει στο defined($slurp = readline $fh) να διακρίνει ένα κενό αρχείο από ένα ανύπαρκτο χωρίς ξεχωριστό έλεγχο -s.

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

  • $/ - διαχωριστής εγγραφών εισόδου. Ελέγχει τι μετρά ως «μία εγγραφή». Η προεπιλογή είναι "\n". Οι ειδικές τιμές καλύπτονται στην ενότητα Λειτουργίες εγγραφών παρακάτω. Γνωστή και ως $INPUT_RECORD_SEPARATOR ή $RS υπό use English.

  • $. - τρέχων αριθμός γραμμής εισόδου του handle που διαβάστηκε τελευταίο. Η readline αυξάνει την $. μία φορά ανά εγγραφή που επιστρέφεται. Η $. μηδενίζεται όταν το handle κλείνει ρητά με close, αλλά όχι όταν το *ARGV περνά από το ένα αρχείο στο επόμενο - η μέτρηση συνεχίζει σε όλη την είσοδο. Επίσης $INPUT_LINE_NUMBER ή $NR υπό use English.

  • $_ - το προεπιλεγμένο βαθμωτό. Όταν μια κλήση readline (ή το ισοδύναμό της <FH>) χρησιμοποιείται ως συνθήκη βρόχου while ή for, η Perl εκχωρεί έμμεσα το αποτέλεσμα στο $_ και ελέγχει defined, όχι αλήθεια. Έτσι, το while (<$fh>) { ... } είναι ασφαλές σε γραμμές που περιέχουν "0" ή "".

  • $! - errno. Σε σφάλμα ανάγνωσης, η readline επιστρέφει undef (βαθμωτό) ή μια κολοβωμένη λίστα, και ορίζει την $! στο σφάλμα του λειτουργικού.

  • @ARGV - όταν παραλείπεται το EXPR (ή το handle είναι το ARGV), κάθε τέλος αρχείου κάνει την Perl να ανοίξει με open το επόμενο όνομα αρχείου από το @ARGV και να συνεχίσει την ανάγνωση. Κενό @ARGV κάνει το ARGV να διαβάζει το STDIN.

Λειτουργίες εγγραφών#

Η $/ επιλέγει μία από τέσσερις λειτουργίες ανάγνωσης:

  • Λειτουργία γραμμής (προεπιλογή) - η $/ είναι μη κενή συμβολοσειρά. Μια εγγραφή τελειώνει στην επόμενη εμφάνιση εκείνης της συμβολοσειράς. Με την προεπιλογή "\n", μία κλήση επιστρέφει μία γραμμή, περιλαμβανομένης της νέας γραμμής της.

  • Λειτουργία παραγράφου - $/ = "". Μια εγγραφή τελειώνει στην επόμενη σειρά δύο ή περισσοτέρων διαδοχικών νέων γραμμών. Οι κενές γραμμές πριν την πρώτη παράγραφο παραλείπονται· η/οι κενή/ές γραμμή/ές που τερματίζουν περιλαμβάνονται στην επιστρεφόμενη συμβολοσειρά. Χρησιμοποιήστε local $/ = "" για να περιορίσετε την αλλαγή σε ένα μπλοκ.

  • Λειτουργία slurp - $/ = undef. Η πρώτη κλήση επιστρέφει το σύνολο του υπολειπόμενου περιεχομένου του handle ως μία συμβολοσειρά· η επόμενη κλήση επιστρέφει undef. Για κενό αρχείο, δείτε την ειδική περίπτωση στην ενότητα Τι επιστρέφεται.

  • Λειτουργία εγγραφών σταθερού μήκους - $/ = \N (αναφορά σε θετικό ακέραιο) ή $/ = \"N". Κάθε κλήση διαβάζει ακριβώς N bytes, ή λιγότερα στο τέλος αρχείου. Χρήσιμο για binary framing. Το αποτέλεσμα εξακολουθεί να μετρά ως μία εγγραφή για το $..

Οι αλλαγές στην $/ τίθενται σε ισχύ στην επόμενη κλήση readline. Οριοθετήστε τες με local ώστε μια υπορουτίνα να μην αλλάζει σιωπηλά την αντίληψη του καλούντος για το τι σημαίνει «γραμμή».

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

Ιδιωματική ανάγνωση γραμμή προς γραμμή. Η συνθήκη while εκχωρεί έμμεσα στο $_ και ελέγχει defined:

open my $fh, "<", "input.txt" or die "open: $!";
while (<$fh>) {
    chomp;
    print "line $.: $_\n";
}
close $fh;

Ρητή κλήση readline με ανίχνευση σφαλμάτων. Η eof πρέπει να ελέγχεται ξεχωριστά από την τιμή επιστροφής, επειδή μια νόμιμη γραμμή μπορεί να είναι η κενή συμβολοσειρά:

while ( ! eof($fh) ) {
    defined( my $line = readline $fh )
        or die "readline failed: $!";
    # ... process $line ...
}

Slurp ολόκληρου αρχείου σε ένα βαθμωτό:

my $contents = do {
    local $/;                   # undef - slurp mode
    open my $fh, "<", $path or die "open $path: $!";
    readline $fh;
};

Λειτουργία παραγράφου - ανάγνωση ενός μπλοκ επικεφαλίδας μηνύματος σε στιλ RFC-822:

open my $fh, "<", "message.eml" or die $!;
local $/ = "";
my $headers = <$fh>;            # up to the first blank line
my $body    = do { local $/; <$fh> };

Λειτουργία εγγραφών σταθερού μήκους - ανάγνωση μπλοκ 512 bytes από αρχείο συσκευής:

open my $fh, "<:raw", "/dev/sda" or die $!;
local $/ = \512;
while (defined(my $block = <$fh>)) {
    last if length($block) < 512;   # short read at EOF
    # ... process $block ...
}

Περιβάλλον λίστας - τραβήξτε κάθε υπολειπόμενη γραμμή με τη μία. Φθηνό για μικρά αρχεία, καταστροφικό για μεγάλα:

open my $fh, "<", "hosts" or die $!;
my @lines = <$fh>;              # every line, including terminators
chomp @lines;

Ανάγνωση από το *ARGV χωρίς ρητό handle - το κλασικό ιδίωμα φίλτρου της Perl. Το @ARGV καταναλώνεται ως λίστα ονομάτων αρχείων, ή διαβάζεται το STDIN αν το @ARGV είναι κενό:

while (defined(my $line = readline)) {
    print $line;                # cat(1) in one line
}

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

  • EOF έναντι σφάλματος: η readline σε βαθμωτό επιστρέφει undef και για τα δύο. Καλέστε eof($fh) ή ελέγξτε την $! για να τα διακρίνετε. Μέσα σε while (<$fh>) ο βρόχος εξέρχεται και στις δύο περιπτώσεις· προσθέστε ρητό έλεγχο defined μαζί με $! όταν χρειάζεται να τα ξεχωρίσετε.

  • Αρχείο χωρίς τελική νέα γραμμή: η τελευταία εγγραφή επιστρέφεται χωρίς τερματιστή σε λειτουργία γραμμής. Η chomp δεν έχει αποτέλεσμα σε τέτοια τιμή, που είναι η σωστή συμπεριφορά.

  • Λειτουργία παραγράφου σε αρχείο με μόνο κενές γραμμές: επιστρέφει undef αμέσως - δεν υπάρχει μη κενή παράγραφος για να αποδοθεί.

  • Λειτουργία slurp, κενό αρχείο: η πρώτη κλήση επιστρέφει '' (ορισμένη, μηδενικού μήκους)· η δεύτερη επιστρέφει undef. Μην διακλαδώνετε βάσει αλήθειας της πρώτης ανάγνωσης.

  • Λειτουργία σταθερού μήκους με σύντομη ανάγνωση στο EOF: επιστρέφει τα υπολειπόμενα bytes (πιθανώς λιγότερα από N), και κατόπιν undef στην επόμενη κλήση. Ελέγξτε length αν χρειάζεστε ακριβώς N.

  • Το μαγικό handle ARGV: όταν διαβάζετε από το *ARGV, η eof() χωρίς όρισμα επιστρέφει αληθές μόνο στο τέλος όλων των αρχείων του @ARGV, ενώ η eof(ARGV) είναι αληθής στο τέλος κάθε αρχείου. Δεν μπορείτε να χρησιμοποιήσετε το ιδίωμα defined(readline) or die "...: $!" έναντι του *ARGV για να διακρίνετε EOF από σφάλμα - ανοίξτε κάθε όνομα αρχείου μόνοι σας αν χρειάζεστε αυτό.

  • Ήδη κλεισμένο handle: η readline επιστρέφει undef και ορίζει την $! σε "Bad file descriptor". Υπό use warnings εκπέμπεται προειδοποίηση readline() on closed filehandle.

  • Στρώματα κωδικοποίησης: η readline επιστρέφει ό,τι παράγει η στοίβα PerlIO του handle. Ένα στρώμα :utf8 ή :encoding(...) αποκωδικοποιεί bytes σε χαρακτήρες· ένα handle :raw επιστρέφει bytes. Η ανάμιξη μιας πολυβάιτας $/ με handle bytes μπορεί να σπάσει χαρακτήρες.

  • Αλλαγή της $/ ενδιάμεσα σε εγγραφή: μόνο η επόμενη κλήση readline παρατηρεί τον νέο διαχωριστή. Όποια ήδη ενδιάμεσα στον buffer δεδομένα σαρώνονται ξανά ως προς αυτόν.

  • <FH> έναντι <$fh> έναντι <>: όλες αυτές είναι readline εσωτερικά. Το <FH> διαβάζει από το typeglob FH· το <$fh> διαβάζει από το handle στο $fh· το <><<>> για ασφαλέστερο χειρισμό ονομάτων αρχείων) διαβάζει από το *ARGV. Η μορφή <pattern> με οποιοδήποτε άλλο περιεχόμενο είναι glob, όχι readline - εντελώς άλλη συνάρτηση.

  • Εκχώρηση στη συνθήκη βρόχου: το while (my $line = <$fh>) { ... } ελέγχει defined, όχι αλήθεια, μόνο επειδή ο αναλυτής το επανεγγράφει. Το while (($line = <$fh>)) { ... } με τις επιπλέον παρενθέσεις δεν δέχεται την επανεγγραφή, και θα κάνει βρόχο επ” άπειρον σε είσοδο που περιέχει "0\n".

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

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

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

  • open - αποκτήστε το filehandle που καταναλώνει η readline

  • read - ανάγνωση σταθερού μήκους σε bytes που αγνοεί την $/· χρησιμοποιήστε όταν θέλετε μέτρηση σε bytes, όχι εγγραφή

  • getc - ανάγνωση ενός χαρακτήρα, που αγνοεί επίσης την $/

  • eof - ελέγχει αν η επόμενη readline θα επέστρεφε undef· συμπεριφέρεται ειδικά για το *ARGV

  • $/ - διαχωριστής εγγραφών εισόδου· ελέγχει τις λειτουργίες γραμμής, παραγράφου, slurp και σταθερού μήκους

  • $. - τρέχων αριθμός γραμμής εισόδου, αυξάνεται από κάθε επιτυχημένη readline