truncate#
Shorten (or extend) a file to an exact byte length.
truncate adjusts the size of the file opened on FILEHANDLE, or the
file named by EXPR, so it is exactly LENGTH bytes long. Bytes past
LENGTH are discarded. The file’s current read/write position is
not changed — a handle sitting past the new end of file stays
there, which is almost never what you want, so plan a seek
before the next write.
Synopsis#
truncate FILEHANDLE, LENGTH
truncate EXPR, LENGTH
What you get back#
1 on success, undef on failure with $! set to the
underlying errno. A missing platform implementation raises an
exception rather than returning undef; that is an install-time
property, not something to branch on at runtime.
truncate $fh, 0
or die "truncate failed: $!";
Filehandle vs. filename form#
Two forms, chosen by what you already have in hand:
truncate FILEHANDLE, LENGTH— the handle must be open for writing (or read/write). Use this when the caller already owns an open write handle; it avoids a freshopen/closeround-trip and works even after the file has been unlinked.truncate EXPR, LENGTH—EXPRis stringified as a pathname. The file is opened, truncated, and closed internally. Use this when you only have a path and do not need the handle afterwards.
Both forms require write permission on the target. On the filehandle form, that is a property of the open mode; on the pathname form, of the filesystem permissions.
LENGTH semantics#
LENGTHis in bytes, not characters. Encoding layers on the filehandle are irrelevant — the length argument goes straight to the OS.LENGTHless than the current file size discards the tail.LENGTHequal to the current size is a no-op that still succeeds.LENGTHgreater than the current size extends the file with a hole of zero bytes on filesystems that support sparse files, or with literal zero bytes otherwise. Upstreamperlfunccalls this case undefined; in practice it behaves like POSIXftruncate(2)on Linux, which is what pperl targets.
Global state it touches#
$!is set on failure to the underlyingerrno.
Examples#
Empty a logfile without closing the handle the rest of the program is still writing to:
open my $log, "+<", "app.log" or die $!;
truncate $log, 0 or die "truncate: $!";
seek $log, 0, 0; # rewind; see "Position is not reset"
Truncate a file by name, no handle involved:
truncate "scratch.dat", 0
or die "truncate scratch.dat: $!";
Rotate a pre-allocated buffer file down to the used portion:
my $used = tell $fh; # bytes actually written
truncate $fh, $used
or die "truncate: $!";
Extend a file to a fixed size (sparse hole on Linux):
open my $fh, ">", "image.raw" or die $!;
truncate $fh, 1024 * 1024 * 1024 # 1 GiB sparse file
or die "truncate: $!";
Edge cases#
Position is not reset. After
truncate $fh, 0, the handle still remembers whatever offset it had. A followingprint $fh ...without an interveningseekmay write past the new end of file, leaving a zero-filled hole.Read-only handle: truncating a handle opened with
<fails withEBADF/EINVALdepending on the platform. Open with+<(read/write) or>>plus an appropriate mode if you need to truncate through the same handle you read from.Negative
LENGTH: the kernel rejects it andtruncatereturnsundefwith$!set toEINVAL.Directory as
EXPR: fails withEISDIR.truncateis strictly a file operation.File unlinked but still open: the filehandle form works fine — the inode is still there as long as any handle holds it open.
LENGTHlarger than current size: on Linux this extends with a sparse hole; reading the hole yields"\0"bytes. Upstreamperlfuncflags this as undefined, so portable code should not rely on it.Platform without
ftruncate/truncate: raises an exception (The truncate function is unimplemented). Not a concern on pperl’s supported platform (Linux), but matters for portable code.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
open— produce a writable filehandle suitable for the filehandle form oftruncateseek— reposition the handle after truncating, before writing againtell— current offset, useful as theLENGTHargument when trimming to “what I have written so far”sysopen— lower-level open when you need explicit flags (O_TRUNCtruncates at open time;truncateis the after-the-fact equivalent)unlink— reach for this instead when you want the file gone, not merely emptied$!—errnoon failure