How does one shrink a file in C? For example, if I open a 2mb file, do some work and decide only 1mb of the file should still exist, how is this accomplished? I know how to use write( fd,....) to write to a file, but what if I want to carve out certain parts in the middle of a file or truncate it?
7 Answers
You're likely looking for truncate()
ftruncate()
or on windows, SetEndOfFile()
. There's no way to "cut" out a piece of the file, you will need to rewrite it from front and then truncate it.

- 88,732
- 13
- 198
- 189
-
You cannot use truncate to remove data from the start (or middle) of the file. – pmg Mar 07 '11 at 16:08
Almost every real system provides some way to truncate a file, but the C standard doesn't provide it in the standard library.
That means pretty much all you can do is define a function to do the job, and implement that function for each target you care about (e.g., on Windows it'll call SetEndOfFile
, on Unix-like systems it'll call ftruncate
, etc.).
Edit: just to clarify: that only works for the "or truncate it" part of the question. Most file systems don't provide anything to "carve out certain parts in the middle of a file". If you want to remove things from the middle of a file, you generally have to rewrite the whole file, or handle things on your own. The latter typically works out to some sort of database-like structure where don't actually delete data from the middle of the file; instead, you create something like an index that tells about the location of data you care about, and simply marks parts as no longer in use when you delete them. Those parts are then eligible for re-use when/if you add data later. In a few cases, you'll have a "compress" function that takes such a database and rewrites it to eliminate the dead space (but there, again, you're back to rewriting the file).

- 236,525
- 50
- 385
- 514

- 476,176
- 80
- 629
- 1,111
If the file is small enough to fit in RAM, you can read the file, and rewrite only the necessary things back(that is, read the file, close the file, open the file again in write mode, write what's necessary, close). If not, you can create a second file, write in it, then delete the first file and rename the second.
My point is, there is no direct way to just delete some part of the file in the middle.

- 130,161
- 59
- 324
- 434
-
-
@Erik: And therein lies the trouble with the ANSI view of the filesystem. – Conrad Meyer Mar 07 '11 at 17:12
If you want to preserve the previous contents of the file up to some length (a length bigger than zero), then POSIX provides the truncate() and ftruncate() functions for the job.
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
The name indicates the primary purpose - shortening a file. But if the specified length is longer than the previous length, the file grows (zero padding) to the new size. Note that ftruncate() works on a file descriptor, not a FILE *;
you could use:
if (ftruncate(fileno(fp), new_length) != 0)
...error handling...
It is likely, though, that for your purposes, truncate on open is all you need.

- 6,657
- 7
- 35
- 49
-
1He don't want to compress his file, he only want to truncate the unused part. – Fox32 Mar 07 '11 at 16:07
-
You have two options:
- Create a temporary file, write the contents you want out to that, and rename it to the original file
- Read the entire file into memory, edit in memory and use freopen to reopen the file, truncating it

- 1,106
- 11
- 25
The others already answered how to truncate a file. Removing parts in the middle of a file is not possible, though. For this, you'd need to rewrite the whole file.

- 3,667
- 16
- 29