tell#
Επιστρέφει την τρέχουσα θέση σε bytes ενός filehandle.
Η tell αναφέρει πού θα γίνει η επόμενη ανάγνωση ή εγγραφή στο FILEHANDLE, μετρημένη σε bytes από την αρχή του αρχείου. Ζευγαρώστε την με την seek για να αποθηκεύσετε μια θέση τώρα και να επιστρέψετε σε αυτήν αργότερα. Αν παραλειφθεί το FILEHANDLE, η tell αναφέρει τη θέση του handle από το οποίο διαβάστηκε τελευταία - συμπεριλαμβανομένου του σιωπηρού handle μέσα σε βρόχους while (<FH>).
Σύνοψη#
tell FILEHANDLE
tell
Τι επιστρέφεται#
Μη αρνητικό ακέραιο byte offset σε επιτυχία, -1 σε σφάλμα. Η τιμή είναι κατάλληλη ως όρισμα POSITION προς την seek με WHENCE στο 0 (απόλυτη μετάβαση). Σε pipes, FIFOs, υποδοχές, και μερικές φορές στις τυπικές ροές, το υποκείμενο OS δεν έχει θέση επανατοποθέτησης και η tell επιστρέφει -1· το $! δεν τίθεται αναγκαστικά σε εκείνη την περίπτωση, οπότε αντιμετωπίστε το -1 ως το αυθεντικό σήμα αποτυχίας.
my $pos = tell $fh;
die "not a seekable handle" if $pos < 0;
# ... read or write ...
seek $fh, $pos, 0; # back to where we were
Καθολική κατάσταση που επηρεάζει#
Filehandle τελευταίας ανάγνωσης: η μορφή
tellχωρίς όρισμα χρησιμοποιεί το handle από το οποίο έγινε η πιο πρόσφατη ανάγνωση στην τρέχουσα εμβέλεια. Κάθεreadline,<FH>, ή<>το ενημερώνει. Η ανάμιξη τηςtellχωρίς όρισμα με πολλαπλά ενεργά handles είναι πηγή απρόσμενων αποτελεσμάτων - ονομάστε ρητά το handle όταν αμφιβάλλετε.Το
$!δεν είναι αξιόπιστο κανάλι σφαλμάτων εδώ. Ελέγξτε για-1απευθείας αντί να ελέγξετε το$!μετά την κλήση.
Bytes, όχι χαρακτήρες#
Η tell επιστρέφει πάντα byte offset, ακόμα κι όταν το handle έχει στρώμα PerlIO προσανατολισμένο σε χαρακτήρες όπως :encoding(UTF-8) ή :utf8. Αυτό είναι σκόπιμο: η μετατροπή μέτρησης χαρακτήρων σε byte offset σε κωδικοποίηση μεταβλητού πλάτους θα απαιτούσε επανάγνωση του αρχείου από την αρχή. Ο ίδιος κανόνας ισχύει για τις seek και sysseek - όλες μιλούν με bytes.
Συνέπεια: σε αρχείο κειμένου UTF-8 δεν μπορείτε γενικά να χρησιμοποιήσετε την tell για να μετρήσετε χαρακτήρες. Χρησιμοποιήστε την μόνο για να σημάνετε θέση που προτίθεστε να τροφοδοτήσετε ξανά στην seek.
Παραδείγματα#
Απομνημόνευση θέσης, ανάγνωση μπροστά, επιστροφή:
open my $fh, "<", "log.txt" or die $!;
my $mark = tell $fh; # 0
my $first = <$fh>; # read one line
seek $fh, $mark, 0; # rewind to the mark
my $again = <$fh>; # same line again
Καταγραφή του offset τέλους κεφαλίδας ώστε ο μεταγενέστερος κώδικας να μπορεί να επανασαρώσει το σώμα χωρίς επανανάλυση της κεφαλίδας:
while (my $line = <$fh>) {
last if $line =~ /^\r?\n\z/; # blank line ends headers
}
my $body_start = tell $fh;
# ... process body ...
seek $fh, $body_start, 0; # second pass over the body
Η μορφή χωρίς όρισμα χρησιμοποιεί το handle από το οποίο διαβάστηκε τελευταία. Μέσα σε βρόχο while (<>) αυτό το handle είναι το σιωπηρό ARGV:
while (<>) {
print "at ", tell, ": $_"; # offset within the current file
}
Η tell σε pipe επιστρέφει -1 επειδή τα pipes δεν είναι επανατοποθετήσιμα:
open my $ph, "-|", "ls" or die $!;
my $pos = tell $ph; # -1
Filehandles μέσα σε σύνθετες εκφράσεις χρειάζονται την ίδια μορφή μπλοκ όπως με την print - η tell $handles[0] είναι συντακτικό σφάλμα. Χρησιμοποιήστε:
my @handles = (\*STDIN, $fh);
my $pos = tell { $handles[1] };
Οριακές περιπτώσεις#
Κλειστό filehandle: επιστρέφει
-1. Υπόuse warningsεκπέμπεται προειδοποίησηtell() on closed filehandle.Μορφή χωρίς όρισμα, καμία ανάγνωση ακόμα: επιστρέφει
-1. Το «filehandle τελευταίας ανάγνωσης» έχει νόημα μόνο μετά από πραγματική ανάγνωση.Μετά από
sysread/syswrite/sysseek: μη χρησιμοποιείτε τηνtellσε handle που έχετε χειριστεί με την οικογένειαsys*. Αυτές οι συναρτήσεις παρακάμπτουν το buffering του PerlIO· ηtellαναφέρει την ενταμιευμένη θέση, που θα είναι λάθος κατά τα περιεχόμενα του ενταμιευτή. Χρησιμοποιήστεsysseekμε whence1και offset0ως την ασφαλή γιαsys*ερώτηση θέσης.Τυπικές ροές: οι
tell STDIN,tell STDOUT,tell STDERRμπορεί να επιστρέψουν-1ή ένα ουσιαστικό offset ανάλογα με το αν η ροή στηρίζεται σε κανονικό αρχείο (ανακατεύθυνση κελύφους) ή σε τερματικό, pipe, ή υποδοχή.Δεν υπάρχει
systell: δεν υπάρχει ξεχωριστή συνάρτηση για θέση που παρακάμπτει το buffering. Το ιδίωμα είναι:my $pos = sysseek $fh, 0, 1;
Δυαδική κατάσταση έναντι κατάστασης κειμένου σε μη-Linux πλατφόρμες: η pperl στοχεύει μόνο το Linux, οπότε τα offsets της
tellταιριάζουν πάντα με τα ωμά bytes του αρχείου. Στρώματα μετατροπής CRLF που περιπλέκουν τηνtellσε perls οικογένειας Windows δεν εφαρμόζονται εδώ.Κατάσταση προσάρτησης (
>>): μετά απόopen my $fh, ">>", ..., η αρχικήtell $fhμπορεί να αναφέρει0μέχρι την πρώτη εγγραφή, επειδή ορισμένες πλατφόρμες τοποθετούν το handle στο τέλος του αρχείου μόνο σε κάθε εγγραφή. Μη βασίζεστε στην αρχική θέση· γράψτε μία φορά, μετά κάντεtell.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
seek- άλμα σε απόλυτο byte offset που είχε επιστρέψει προηγουμένως ηtellsysseek- ερώτηση και άλμα θέσης για handles που χρησιμοποιούνται μεsysread/syswrite, παρακάμπτοντας το buffering του PerlIOtelldir- το αντίστοιχο για handle καταλόγου· ζευγαρώνει μεseekdireof- έλεγχος για τέλος αρχείου αντί για απόλυτη θέσηopen- δημιουργία του filehandle εξαρχής· το mode και τα στρώματα PerlIO καθορίζουν αν το handle είναι επανατοποθετήσιμο