I/O · Δεδομένα σταθερού μήκους
syswrite#
Γράφει bytes σε filehandle με την ακατέργαστη κλήση συστήματος write(2), παρακάμπτοντας το ενταμιευμένο I/O της Perl.
Η syswrite παραδίδει LENGTH bytes από το SCALAR απευθείας στον πυρήνα μέσω της write(2), παρακάμπτοντας την ενταμίευση PerlIO από την οποία περνούν οι print, printf και write. Ο πυρήνας ενδέχεται να δεχτεί λιγότερα bytes από όσα ζητήθηκαν - η syswrite επιστρέφει ό,τι όντως έγραψε, και ο καλογραμμένος κώδικας ελέγχει πάντα. Αν παραλειφθεί το LENGTH, γράφεται ολόκληρο το SCALAR. Ένα προαιρετικό OFFSET ξεκινά την εγγραφή σε θέση διαφορετική από την αρχή της συμβολοσειράς.
Σύνοψη#
syswrite FILEHANDLE, SCALAR, LENGTH, OFFSET
syswrite FILEHANDLE, SCALAR, LENGTH
syswrite FILEHANDLE, SCALAR
Τι επιστρέφεται#
Το πλήθος των bytes που όντως γράφτηκαν, ή undef σε σφάλμα (με ρυθμισμένο το $!). Το επιστρεφόμενο πλήθος μπορεί να είναι μικρότερο από το LENGTH. Αυτό είναι φυσιολογικό σε pipes, υποδοχές, και μη μπλοκαριστικά handles· δεν είναι σφάλμα. Κώδικας που χρειάζεται να παραδώσει κάθε byte πρέπει να επαναλαμβάνει σε βρόχο:
my $off = 0;
my $len = length $buf;
while ($off < $len) {
my $n = syswrite $fh, $buf, $len - $off, $off;
defined $n or die "write failed: $!";
$off += $n;
}
Επιστροφή 0 είναι νόμιμη και σημαίνει «δεν γράφτηκαν bytes σε αυτή την κλήση, ξαναπροσπαθήστε» - όχι τέλος ροής. Το undef είναι το μόνο σήμα σφάλματος.
Καθολική κατάσταση που επηρεάζει#
Καμία αλληλεπίδραση με τα
$,,$\, ή$|. Ηsyswriteδεν μορφοποιεί, δεν προσαρτά διαχωριστές εγγραφής, και δεν τηρεί τη σημαία autoflush επειδή δεν υπάρχει ενταμιευτής προς εκκένωση - τα bytes πηγαίνουν κατευθείαν στον πυρήνα.Καμία αλληλεπίδραση με το επιλεγμένο filehandle από τη
select. ΤοFILEHANDLEείναι υποχρεωτικό· δεν υπάρχει προεπιλογή.
Παραδείγματα#
Εγγραφή συμβολοσειράς αυτολεξεί στο STDOUT, χωρίς προσθήκη διαχωριστών:
syswrite STDOUT, "hello\n"; # 6 bytes written
Εγγραφή εγγραφής σταθερού μεγέθους και έλεγχος για σύντομη εγγραφή:
my $rec = pack "A8 N", $name, $id; # 12 bytes
my $n = syswrite $fh, $rec;
defined $n or die "syswrite: $!";
$n == length $rec or die "short write: $n of ${\length $rec}";
Εγγραφή από τη μέση ενός ενταμιευτή με OFFSET. Χρήσιμο μέσα σε βρόχο εκκένωσης όπου το $off παρακολουθεί πόσα έχουν γίνει δεκτά μέχρι στιγμής:
my $buf = "ABCDEFGHIJ";
syswrite $fh, $buf, 4, 3; # writes "DEFG"
Αρνητικό OFFSET μετράει από το τέλος:
my $buf = "ABCDEFGHIJ";
syswrite $fh, $buf, 3, -4; # writes "GHI"
Εγγραφή σε μη μπλοκαριστική υποδοχή και χειρισμός του EAGAIN:
use Errno qw(EAGAIN EWOULDBLOCK);
my $n = syswrite $sock, $buf;
if (!defined $n) {
if ($! == EAGAIN || $! == EWOULDBLOCK) {
# kernel buffer full - try again after select()
} else {
die "syswrite: $!";
}
}
Οριακές περιπτώσεις#
Μην αναμειγνύετε με ενταμιευμένο I/O στο ίδιο handle. Η
syswriteπαρακάμπτει τοPerlIO, αλλά οιprint,printf,write,seek,tellκαιeofπερνούν όλες από τα στρώματα ενταμίευσης:perlioκαι:crlf. Η διαπλοκή τους σε ένα handle αλλοιώνει τη σειρά εξόδου. Επιλέξτε μία λειτουργία ανά handle. Αν πρέπει να αναμείξετε, χρησιμοποιήστε τους κανόνες συμμετρίαςread/sysreadκαι να είστε προσεκτικοί.Οι σύντομες εγγραφές είναι φυσιολογικές. Τα pipes, οι υποδοχές, τα τερματικά και τα μη μπλοκαριστικά handles τακτικά δέχονται λιγότερα bytes από αυτά που προσφέρονται. Το ιδίωμα βρόχου εκκένωσης παραπάνω είναι το σωστό μοτίβο για κάθε handle όπου οι σύντομες εγγραφές έχουν σημασία.
Τιμή επιστροφής
0σημαίνει ότι ο πυρήνας δέχτηκε μηδέν bytes σε αυτή την κλήση. Δεν είναι τέλος ροής ούτε σφάλμα· επαναλάβετε.Μήκος μεγαλύτερο από τα διαθέσιμα δεδομένα: αν το
LENGTHυπερβαίνει τοlength(SCALAR) - OFFSET, γράφονται μόνο τα διαθέσιμα bytes και αυτό το πλήθος επιστρέφεται.Κενό SCALAR: αν το
SCALARέχει μηδενικό μήκος, τοOFFSETπρέπει να είναι0. Οποιαδήποτε άλλη τιμή εγείρει εξαίρεση.Τα στρώματα
:utf8και:encoding(...)εγείρουν εξαίρεση. Ηsyswriteλειτουργεί σε bytes, όχι χαρακτήρες, και αρνείται οποιοδήποτε handle φέρει στρώμα κωδικοποίησης UTF-8. Το:encoding(...)προσθέτει σιωπηρά το:utf8, οπότε απαγορεύεται εξίσου. Χρησιμοποιήστεbinmodeγια να αφαιρέσετε το στρώμα, ή γράψτε μέσωprintαντ’ αυτού.Χαρακτήρες πάνω από το U+00FF σε handle λειτουργίας bytes εγείρουν επίσης εξαίρεση - δεν υπάρχει τρόπος να σειριοποιηθεί ένα codepoint μεγαλύτερο από
0xFFως μονό byte. Κωδικοποιήστε ρητά τη συμβολοσειρά πριν την κλήση τηςsyswrite:use Encode qw(encode); syswrite $fh, encode("UTF-8", $text);
Σπασμένο pipe / κλειστή υποδοχή εγείρει
SIGPIPE. Η προεπιλεγμένη ενέργεια τερματίζει τη διεργασία. Εγκαταστήστε$SIG{PIPE} = 'IGNORE'(ή χειριστή) για να μετατρέψετε αυτό σε κανονικό σφάλμαsyswriteμε το$!ρυθμισμένο σεEPIPE.Κλεισμένο filehandle επιστρέφει
undefμε το$!ρυθμισμένο σε"Bad file descriptor"· υπόuse warningsεκπέμπεται προειδοποίησηsyswrite() on closed filehandle.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
sysread- το αντίστοιχο ανάγνωσης· ίδια σημασιολογία παράκαμψης ενταμιευτή και ίδιος επιφυλακτικός όρος για σύντομη ανάγνωσηsysopen- ανοίγει handle σε επίπεδοopen(2)ώστε ηsyswriteνα μπορεί να επικοινωνήσει με αυτό χωρίς να παρεμβάλλονται στρώματα μετάφρασηςPerlIOsysseek- επανατοποθετεί το handle χρησιμοποιώντας τηνlseek(2), συνδυάζεται με τηνsyswriteγια I/O τυχαίας πρόσβασης σε ακατέργαστα handlesprint- η ενταμιευμένη αντίστοιχη που σχεδόν πάντα θέλετε αντ’ αυτής· τηρεί τα$,,$\και$|binmode- αφαιρεί στρώμα:utf8ή:encoding(...)από handle ώστε να μπορεί να χρησιμοποιηθεί ηsyswriteσε αυτό$!- επιθεωρήστε το μετά από επιστροφήundefγια να διακρίνετε τοEAGAINαπό πραγματική αποτυχία