I/O

truncate#

Συντομεύει (ή επεκτείνει) ένα αρχείο σε ακριβές μήκος bytes.

Η truncate ρυθμίζει το μέγεθος του αρχείου που είναι ανοιχτό στο FILEHANDLE, ή του αρχείου που κατονομάζεται από την EXPR, ώστε να είναι ακριβώς LENGTH bytes μακρύ. Τα bytes πέρα από το LENGTH απορρίπτονται. Η τρέχουσα θέση ανάγνωσης/εγγραφής του αρχείου δεν αλλάζει - ένα handle που βρίσκεται πέρα από το νέο τέλος αρχείου παραμένει εκεί, που σχεδόν ποτέ δεν είναι αυτό που θέλετε, οπότε σχεδιάστε μια seek πριν την επόμενη εγγραφή.

Σύνοψη#

truncate FILEHANDLE, LENGTH
truncate EXPR, LENGTH

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

1 σε επιτυχία, undef σε αποτυχία με το $! τεθειμένο στο υποκείμενο errno. Μια απουσία υλοποίησης σε πλατφόρμα εγείρει εξαίρεση αντί να επιστρέψει undef· αυτή είναι ιδιότητα κατά την εγκατάσταση, όχι κάτι για διακλάδωση σε χρόνο εκτέλεσης.

truncate $fh, 0
    or die "truncate failed: $!";

Μορφή filehandle έναντι ονόματος αρχείου#

Δύο μορφές, που επιλέγονται από αυτό που έχετε ήδη στα χέρια σας:

  • truncate FILEHANDLE, LENGTH - το handle πρέπει να είναι ανοιχτό για εγγραφή (ή ανάγνωση/εγγραφή). Χρησιμοποιήστε αυτή τη μορφή όταν ο καλών κατέχει ήδη ανοιχτό handle εγγραφής· αποφεύγει έναν φρέσκο πλήρη κύκλο open/close και λειτουργεί ακόμη και μετά το unlink του αρχείου.

  • truncate EXPR, LENGTH - η EXPR μετατρέπεται σε συμβολοσειρά ως διαδρομή. Το αρχείο ανοίγει, αποκόπτεται και κλείνει εσωτερικά. Χρησιμοποιήστε αυτή τη μορφή όταν έχετε μόνο διαδρομή και δεν χρειάζεστε το handle στη συνέχεια.

Και οι δύο μορφές απαιτούν δικαίωμα εγγραφής στον στόχο. Στη μορφή filehandle, αυτό είναι ιδιότητα της λειτουργίας ανοίγματος· στη μορφή διαδρομής, των δικαιωμάτων του filesystem.

Σημασιολογία LENGTH#

  • Το LENGTH είναι σε bytes, όχι χαρακτήρες. Τα στρώματα κωδικοποίησης στο filehandle είναι άσχετα - το όρισμα μήκους πάει απευθείας στο OS.

  • Το LENGTH μικρότερο από το τρέχον μέγεθος του αρχείου απορρίπτει την ουρά.

  • Το LENGTH ίσο με το τρέχον μέγεθος είναι no-op που εξακολουθεί να πετυχαίνει.

  • Το LENGTH μεγαλύτερο από το τρέχον μέγεθος επεκτείνει το αρχείο με τρύπα μηδενικών bytes σε filesystems που υποστηρίζουν αραιά αρχεία, ή με κυριολεκτικά μηδενικά bytes διαφορετικά. Το upstream perlfunc χαρακτηρίζει αυτή την περίπτωση απροσδιόριστη· στην πράξη συμπεριφέρεται όπως η POSIX ftruncate(2) σε Linux, που είναι αυτό που στοχεύει η pperl.

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

  • Το $! τίθεται σε αποτυχία στο υποκείμενο errno.

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

Αδειάστε ένα αρχείο καταγραφής χωρίς να κλείσετε το handle στο οποίο το υπόλοιπο πρόγραμμα ακόμη γράφει:

open my $log, "+<", "app.log" or die $!;
truncate $log, 0 or die "truncate: $!";
seek $log, 0, 0;                # rewind; see "Position is not reset"

Αποκόψτε ένα αρχείο με όνομα, χωρίς να εμπλέκεται handle:

truncate "scratch.dat", 0
    or die "truncate scratch.dat: $!";

Περιστρέψτε ένα προεκχωρημένο αρχείο ενταμιευτή στο χρησιμοποιούμενο τμήμα:

my $used = tell $fh;            # bytes actually written
truncate $fh, $used
    or die "truncate: $!";

Επεκτείνετε ένα αρχείο σε σταθερό μέγεθος (αραιή τρύπα σε Linux):

open my $fh, ">", "image.raw" or die $!;
truncate $fh, 1024 * 1024 * 1024   # 1 GiB sparse file
    or die "truncate: $!";

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

  • Η θέση δεν επαναφέρεται. Μετά την truncate $fh, 0, το handle εξακολουθεί να θυμάται όποιο offset είχε. Μια ακόλουθη print $fh ... χωρίς ενδιάμεση seek μπορεί να γράψει πέρα από το νέο τέλος αρχείου, αφήνοντας μηδενοσυμπληρωμένη τρύπα.

  • Handle μόνο για ανάγνωση: η αποκοπή handle ανοιγμένου με < αποτυγχάνει με EBADF / EINVAL ανάλογα με την πλατφόρμα. Ανοίξτε με +< (ανάγνωση/εγγραφή) ή >> συν κατάλληλη λειτουργία αν χρειάζεται να αποκόψετε μέσω του ίδιου handle από το οποίο διαβάσατε.

  • Αρνητικό LENGTH: ο πυρήνας το απορρίπτει και η truncate επιστρέφει undef με το $! τεθειμένο σε EINVAL.

  • Κατάλογος ως EXPR: αποτυγχάνει με EISDIR. Η truncate είναι αυστηρά λειτουργία αρχείου.

  • Αρχείο με unlink αλλά ακόμη ανοιχτό: η μορφή filehandle λειτουργεί καλά - το inode εξακολουθεί να υπάρχει εφόσον κάποιο handle το κρατά ανοιχτό.

  • LENGTH μεγαλύτερο από το τρέχον μέγεθος: σε Linux αυτό επεκτείνει με αραιή τρύπα· η ανάγνωση της τρύπας αποδίδει bytes "\0". Το upstream perlfunc το επισημαίνει ως απροσδιόριστο, οπότε φορητός κώδικας δεν θα έπρεπε να βασιστεί σε αυτό.

  • Πλατφόρμα χωρίς ftruncate/truncate: εγείρει εξαίρεση (The truncate function is unimplemented). Όχι θέμα στην υποστηριζόμενη πλατφόρμα της pperl (Linux), αλλά έχει σημασία για φορητό κώδικα.

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

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

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

  • open - παράγετε εγγράψιμο filehandle κατάλληλο για τη μορφή filehandle της truncate

  • seek - επανατοποθετήστε το handle μετά την αποκοπή, πριν την εγγραφή ξανά

  • tell - τρέχον offset, χρήσιμο ως όρισμα LENGTH όταν περικόπτετε σε «αυτό που έχω γράψει μέχρι τώρα»

  • sysopen - χαμηλότερου επιπέδου άνοιγμα όταν χρειάζεστε ρητές σημαίες (η O_TRUNC αποκόπτει κατά τον χρόνο ανοίγματος· η truncate είναι το ισοδύναμο εκ των υστέρων)

  • unlink - επιλέξτε αυτή αντί γι” αυτό όταν θέλετε το αρχείο να εξαφανιστεί, όχι απλώς να αδειάσει

  • $! - errno σε αποτυχία