Node:File Size, Previous:File Times, Up:File Attributes
Normally file sizes are maintained automatically. A file begins with a
size of 0 and is automatically extended when data is written past
its end. It is also possible to empty a file completely by an
open
or fopen
call.
However, sometimes it is necessary to reduce the size of a file.
This can be done with the truncate
and ftruncate
functions.
They were introduced in BSD Unix. ftruncate
was later added to
POSIX.1.
Some systems allow you to extend a file (creating holes) with these
functions. This is useful when using memory-mapped I/O
(see Memory-mapped I/O), where files are not automatically extended.
However, it is not portable but must be implemented if mmap
allows mapping of files (i.e., _POSIX_MAPPED_FILES
is defined).
Using these functions on anything other than a regular file gives undefined results. On many systems, such a call will appear to succeed, without actually accomplishing anything.
int truncate (const char *filename, off_t length) | Function |
The If length is longer, holes will be added to the end. However, some systems do not support this feature and will leave the file unchanged. When the source file is compiled with The return value is 0 for success, or -1 for an error. In addition to the usual file name errors, the following errors may occur:
|
int truncate64 (const char *name, off64_t length) | Function |
This function is similar to the truncate function. The
difference is that the length argument is 64 bits wide even on 32
bits machines, which allows the handling of files with sizes up to
2^63 bytes.
When the source file is compiled with |
int ftruncate (int fd, off_t length) | Function |
This is like The POSIX standard leaves it implementation defined what happens if the
specified new length of the file is bigger than the original size.
The
When the source file is compiled with The return value is 0 for success, or -1 for an error. The following errors may occur:
|
int ftruncate64 (int id, off64_t length) | Function |
This function is similar to the ftruncate function. The
difference is that the length argument is 64 bits wide even on 32
bits machines which allows the handling of files with sizes up to
2^63 bytes.
When the source file is compiled with |
As announced here is a little example of how to use ftruncate
in
combination with mmap
:
int fd; void *start; size_t len; int add (off_t at, void *block, size_t size) { if (at + size > len) { /* Resize the file and remap. */ size_t ps = sysconf (_SC_PAGESIZE); size_t ns = (at + size + ps - 1) & ~(ps - 1); void *np; if (ftruncate (fd, ns) < 0) return -1; np = mmap (NULL, ns, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (np == MAP_FAILED) return -1; start = np; len = ns; } memcpy ((char *) start + at, block, size); return 0; }
The function add
writes a block of memory at an arbitrary
position in the file. If the current size of the file is too small it
is extended. Note the it is extended by a round number of pages. This
is a requirement of mmap
. The program has to keep track of the
real size, and when it has finished a final ftruncate
call should
set the real size of the file.