File Truncation

This week, I will show how to truncate files using the truncate() and

ftruncate() syscalls.

The file system automatically expands a file's size as more data is

appended to it; however, it has no way of knowing how to shrink a file

when the data at its end is no longer needed. Consider the following

scenario: You have a log file that contains a header at its beginning

and a varying number of fixed-size records. You want to keep the log

file for a certain amount of time (say up to a week after the last

record was appended) and then shrink it to its original size (i.e.,

remove the records while keeping the header) so that new records will

be appended after the header. One way to do this is copying the header

to another file, delete the original file, and rename the copy.

However, there is a simpler way to achieve the same effect. The

header declares two syscalls that truncate files, namely truncate() and ftruncate(). Here are their prototypes: int truncate (const char * path, size_t length); int ftruncate (int fd, size_t length); truncate() takes a filename as its first argument. It sets the file's size to length, discarding any trailing bytes past the new end. If length is larger than the current file size, then the file is expanded accordingly. The ftruncate() syscall is similar to truncate() except that it takes a file descriptor rather than a filename. Remember that when using ftruncate(), the file descriptor must refer to an open file. In the following example, the program accepts a filename as a command line argument, displays its current size, prompts the user for a new size and truncates it accordingly: #include #include #include #include int main(int argc, char * argv[]) { struct stat info; size_t len; if(argc<2) { printf("filename not provided, aborting\n"); exit(1); } if (stat(argv[1], &info)) { printf("stat() error, exit forced"); exit(1); } printf("size of file %s is: %d \n", argv[1], info.st_size); printf("enter new size: \n") scanf("%d", &length); if (!truncate (argv[1], len)) { printf("file %s was truncated successfully\n", argv[1]); } else { printf("truncation failed"); exit(1); } return 0; }
What’s wrong? The new clean desk test
Join the discussion
Be the first to comment on this article. Our Commenting Policies