shrinking a file

Started by
5 comments, last by DaBono 18 years, 7 months ago
Hi Is there any other way to shrink a file when deleteing some content instead of caching the whole file and overwriting the old one e.g.: pak files(binary not text files) i remove an entry and want to rebuild is there a way to move the end of file indicator backwards towards the beginning of the file?
http://www.8ung.at/basiror/theironcross.html
Advertisement
SetEndOfFile on Windows, ftruncate (I think that was it) on POSIX.
ok i checked out the ofstream class it offeres a truncate flag
which discards the content of the you opened

could i just move the filepointer to the location where i deleted some content
and append the entries that are placed behind the deleted entry to this location so i would proceed as follows

1. open file for reading
2. read content behind the deleted entry
3. store offset of deleted entry
4. close file
5. open file for writing the ios:trunc flag set
6. seek to deleted entry's offset
7. write cached content over deleted entry thus moving all entrys behind the deleted one forward
8. close

or are there any other methods like matching the chunk size of an entry to the next largest 4kb block
so you can copy blocks around


any suggestions?
in truncate mode i move the file pointer to the new EOF position so the eof is placed behind content of the pakfile and I don t loose any data
http://www.8ung.at/basiror/theironcross.html
When you open a file in truncate mode, its entire contents are immediately deleted. Thus, you can't move the file pointer anywhere because the file's data length is 0 bytes and any attempt to move the file pointer would result in an error.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
I'd do something like this (of the top of my head, may not compile/work as-is):
// Open filesFILE *in = fopen(filename, "r");FILE *out = fopen(filename, "a");if( (NULL == in) || (NULL == out) )   return;// Position in at the first part that should be kept, out at the// position of the empty spacefseek( in,  deletedFileOffset+deletedFileSize, SEEK_SET );fseek( out, deletedFileOffset, SEEK_SET );// Write everything after the deleted file back a few byteschar buf[4096];int n;while( (n = fread(buf, 1, 4096, in)) > 0 )   fwrite(buf, 1, n, out);// Truncate that file, and close themfclose(in);ftruncate( fileno(out), ftell(out) );fclose(out);

EDIT: Added comments
Quote:Original post by Extrarius
When you open a file in truncate mode, its entire contents are immediately deleted. Thus, you can't move the file pointer anywhere because the file's data length is 0 bytes and any attempt to move the file pointer would result in an error.


from the MSDN so i guess this should work

dabono this is basically what i want to do

is there a maximum size you can read from file?

if not i could read everything at once and and update the offsets in the filetable all at once
http://www.8ung.at/basiror/theironcross.html
Quote:is there a maximum size you can read from file?
if not i could read everything at once and and update the offsets in the filetable all at once

I'm not sure I understand your question.
The fseek and ftell-functions are limited to searching in max. 2GB files. There are functions called fseeko and ftello that raise this limit to 4TB.
You can update your file offsets while you write, although you know them beforehand (the files after the deleted file shift back the size of the file).
During the loop, there is never more dan 4 KB in memory.

This topic is closed to new replies.

Advertisement