I/O · Δεδομένα σταθερού μήκους
sysread#
Διαβάζει ωμά bytes από ένα filehandle καλώντας την υποκείμενη κλήση συστήματος read(2).
Η sysread προσπαθεί να διαβάσει LENGTH bytes από το FILEHANDLE και να τα αποθηκεύσει στο SCALAR. Παρακάμπτει τη στοίβα ενταμίευσης του PerlIO, που είναι ο όλος σκοπός - οι αναγνώσεις πηγαίνουν κατευθείαν στον πυρήνα και επιστρέφουν ό,τι επιστρέφει μία μεμονωμένη read(2), που μπορεί να είναι λιγότερα bytes από αυτά που ζητήθηκαν. Χρησιμοποιήστε την για υποδοχές, σωλήνες, συσκευές και κάθε άλλη κατάσταση όπου θέλετε έλεγχο πάνω σε μεμονωμένες κλήσεις συστήματος αντί για είσοδο προσανατολισμένη σε γραμμή ή εγγραφή.
Σύνοψη#
sysread FILEHANDLE, SCALAR, LENGTH
sysread FILEHANDLE, SCALAR, LENGTH, OFFSET
Τι επιστρέφεται#
Ο αριθμός των bytes που διαβάστηκαν πραγματικά, που μπορεί να είναι λιγότερα από το
LENGTHσε υποδοχές, σωλήνες, ttys και κατά τη διάρκεια διακοπής από σήμα.0στο τέλος αρχείου.undefσε σφάλμα, με την$!ορισμένη στηνerrnoτης αποτυχημένηςread(2).
Το SCALAR μεγαλώνει ή συρρικνώνεται ώστε το τελευταίο byte που διαβάστηκε να γίνει το τελευταίο byte του βαθμωτού. Μετά από σύντομη ανάγνωση, το βαθμωτό κρατά μόνο τα bytes που ελήφθησαν πραγματικά - τίποτα δεν συμπληρώνεται με μηδενικά μέχρι το LENGTH.
my $n = sysread $sock, my $buf, 4096;
defined $n or die "read failed: $!";
$n == 0 and return; # peer closed
process_chunk($buf); # length($buf) == $n
Καθολική κατάσταση που επηρεάζει#
$!- τίθεται όταν ηsysreadεπιστρέφειundef. Οι διακοπείσες αναγνώσεις εμφανίζονται ωςEINTR· οι αναγνώσεις που θα μπλόκαραν σε μη μπλοκαριστικά handles εμφανίζονται ωςEAGAIN/EWOULDBLOCK.Το ίδιο το
SCALAR- του γίνεται πάντα ανάθεση, ακόμη και σε αποτυχία (αποκόπτεται σεOFFSETbytes όταν δίνεταιOFFSETκαι η ανάγνωση αποτυγχάνει ή επιστρέφει μηδέν).Η θέση byte του filehandle προωθείται κατά τον αριθμό των bytes που επιστράφηκαν· αυτή είναι η ίδια θέση σε επίπεδο πυρήνα που χειρίζεται η
sysseek.
Η sysread δεν συμβουλεύεται ούτε αγγίζει τις $/, $\, $,, ή $_. Είναι πρωτογενής λειτουργία επιπέδου byte· η σημασιολογία εγγραφών δεν εφαρμόζεται.
OFFSET - πού προσγειώνονται τα bytes μέσα στο SCALAR#
Χωρίς OFFSET, το SCALAR αντικαθίσταται από τα bytes που διαβάστηκαν.
Με OFFSET, τα bytes γράφονται μέσα στο SCALAR ξεκινώντας από εκείνη τη θέση:
OFFSET >= 0- αρχίζει η εγγραφή στο byteOFFSET. Αν τοOFFSETείναι μεγαλύτερο από το τρέχον μήκος τουSCALAR, η συμβολοσειρά συμπληρώνεται πρώτα με"\0"bytes μέχρι τοOFFSET, και κατόπιν προστίθενται τα νέα δεδομένα.OFFSET < 0- μετριέται προς τα πίσω από το τέλος τουSCALAR. Το-1σημαίνει «αντικατάσταση του τελευταίου byte», το-10σημαίνει «αντικατάσταση των τελευταίων 10 bytes».
Έτσι μεγαλώνετε σταδιακά έναν ενταμιευτή χωρίς επαναλαμβανόμενη συνένωση:
my $buf = "";
while ((my $n = sysread $fh, $buf, 8192, length $buf) > 0) {
# each call appends at the current end of $buf
}
defined $n or die "read failed: $!";
Παραδείγματα#
Ανάγνωση έως 64 bytes από αρχείο. Το $buf καταλήγει ακριβώς $n bytes σε μήκος:
open my $fh, "<", "input.bin" or die $!;
my $n = sysread $fh, my $buf, 64;
defined $n or die "sysread: $!";
Ανάγνωση έως 32 bytes και τοποθέτησή τους ξεκινώντας από τη θέση 512 στο $buf, με συμπλήρωση "\0" αν το $buf ήταν μικρότερο:
my $buf = "header";
my $n = sysread $fh, $buf, 32, 512; # $buf is now 512 + $n bytes
Αποστράγγιση υποδοχής μέχρι να κλείσει ο ομότιμος. Ο έλεγχος για 0 - όχι για eof - είναι ο μόνος σωστός έλεγχος τέλους ροής για την sysread:
while (1) {
my $n = sysread $sock, my $chunk, 4096;
defined $n or die "read: $!";
last if $n == 0; # orderly shutdown from peer
handle($chunk);
}
Επανεκκίνηση ανάγνωσης που διέκοψε σήμα. Σε μπλοκαριστικό handle, το EINTR είναι η μία αποτυχία που τυπικά επανεπιχειρείτε αντί να διαδώσετε:
use Errno qw(EINTR);
my $n;
RETRY: {
$n = sysread $fh, my $buf, $want;
redo RETRY if !defined $n && $! == EINTR;
}
defined $n or die "read: $!";
Γέμισμα εγγραφής σταθερού μεγέθους, ανεκτικά απέναντι σε σύντομες αναγνώσεις. Μία sysread μπορεί να επιστρέψει λιγότερα bytes από όσα ζητήθηκαν ακόμη και σε κανονικό αρχείο κοντά στο EOF, και τακτικά το κάνει σε υποδοχές και σωλήνες:
sub read_exact {
my ($fh, $want) = @_;
my $buf = "";
while (length($buf) < $want) {
my $n = sysread $fh, $buf, $want - length($buf), length $buf;
defined $n or die "read: $!";
$n == 0 and die "short read: got ", length $buf, " of $want";
}
return $buf;
}
Οριακές περιπτώσεις#
Ποτέ μην αναμιγνύετε με ενταμιευμένο I/O στο ίδιο handle. Οι
readline,read,<$fh>,getc,eof,seekκαιtellπερνούν όλες από ενταμιευτές PerlIO· ηsysreadτους παρακάμπτει. Η διαπλοκή τους στο ίδιο handle αφήνει δεδομένα εγκλωβισμένα στον ενταμιευτή που ηsysreadδεν θα δει ποτέ, ή προσπερνά δεδομένα που ο ενταμιευμένος αναγνώστης κατανάλωσε ήδη. Χρησιμοποιήστε ένα στυλ ανά handle.Το
:utf8απαγορεύεται. Handle με στρώμα:utf8(συμπεριλαμβανομένου του έμμεσου στρώματος που προστίθεται από το:encoding(...)) κάνει τηνsysreadνα εκτοξεύσει εξαίρεση. Αφαιρέστε το στρώμα μεbinmode- ηbinmode $fhχωρίς δεύτερο όρισμα επαναφέρει ωμά bytes - πριν καλέσετε τηνsysread.Το
:crlf/:perlioεντάμιεύουν παρ” όλα αυτά. Ακόμη και χωρίς:utf8, η προεπιλεγμένη στοίβα:perlioεντάμιεύει αναγνώσεις και μεταφράζει τερματισμούς γραμμών υπό:crlf. Ηsysreadαγνοεί εκείνα τα στρώματα, οπότε bytes που ο ενταμιευμένος αναγνώστης τράβηξε ήδη στον ενταμιευτή PerlIO χάνονται σιωπηρά για τηνsysread. Ανοίξτε handles προοριζόμενα γιαsysreadμεsysopenή καλέστεbinmode $fhγια να απενεργοποιήσετε το:crlf.Οι σύντομες αναγνώσεις είναι κανονικές, όχι σφάλματα. Επιστροφή
$nμε0 < $n < LENGTHείναι επιτυχία. Μόνο τοundefυποδηλώνει αποτυχία· το0υποδηλώνει EOF. Κάντε βρόχο μέχρι να έχετε ό,τι χρειάζεστε.Δεν υπάρχει
syseof. Δεν υπάρχει ξεχωριστός έλεγχος τέλους-αρχείου για τηνsysread· ηeofκοιτά τον ενταμιευτή PerlIO και είναι άνευ νοήματος εδώ. Η τιμή επιστροφής0είναι το σήμα τέλους-αρχείου.OFFSETπέρα από το τρέχον μήκος. Ηsysread $fh, $buf, 10, 1_000_000συμπληρώνει το$bufμε ένα εκατομμύριο"\0"bytes πριν γράψει. Αυτό είναι περιστασιακά χρήσιμο για προ-δέσμευση, αλλά συνήθως είναι σφάλμα.Το αρνητικό
OFFSETμετριέται από το τρέχον τέλος τουSCALAR, όχι από τοLENGTH. Ηsysread $fh, $buf, 4, -4αντικαθιστά τα τελευταία τέσσερα bytes ό,τι κρατά αυτή τη στιγμή το$buf.Μη μπλοκαριστικά handles. Σε handle με
O_NONBLOCKορισμένο, μια ανάγνωση χωρίς διαθέσιμα δεδομένα επιστρέφειundefμε την$!ίση μεEAGAINήEWOULDBLOCK. Αντιμετωπίστε το ως «δοκιμάστε αργότερα», όχι ως σφάλμα.Σήματα. Μια μπλοκαριστική
sysreadπου διακόπτεται από σήμα επιστρέφειundefμε την$!ίση μεEINTR. Επαναλάβετε την κλήση.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
syswrite- το αντίστοιχο της πλευράς εγγραφής· ίδιοι κανόνες ενταμίευσης, ίδια σημασιολογία σύντομου I/Osysopen- ανοίγει handle με ωμές σημαίεςopen(2), ο φυσικός συνεργάτης τηςsysreadσε αρχείαsysseek- αναζήτηση ακριβείας byte που συντίθεται σωστά με τηνsysread· μην αναμιγνύετεseekμεsysreadread- το ενταμιευμένο αντίστοιχο· χρησιμοποιήστε την για είσοδο προσανατολισμένη σε γραμμή ή εγγραφή, όχι για υποδοχές ή μερικές αναγνώσειςbinmode- αφαιρεί:utf8ή:crlfαπό handle πριν τη χρήση τηςsysread$!- η τιμήerrnoμετά από αποτυχημένηsysread, συμπεριλαμβανομένων τωνEINTR,EAGAINκαιEWOULDBLOCK