What is the best way to truncate the beginning of a file in C?

There are many similar questions, but nothing that answers this specifically after a multiplayer game. Here:

Let's say we have a file (maybe binary and much more):

abcdefghijklmnopqrztuvwxyz

What is the best way in C to "move" the right most of this file to the left, truncating the beginning of the file .. so, for example, "truncating the front" of 7 bytes will change the file on disk to be:

hijklmnopqrztuvwxyz

I should avoid temporary files and prefer not to use a large buffer to read the entire file in memory. One of the possible methods that I was thinking about is to use fopen with the "rb +" flag and constantly read and write read and write to copy bytes, starting from the offset to the beginning, and then trim setEndOfFile at the end. It seems like a lot (possibly inefficient).

Another way would be to open the same file twice and use fgetc and fputc with the corresponding file pointers. Is it possible?

If there are other ways, I would love to read them all.

+6
source share
3 answers

You do not need to use a huge buffer size, and the kernel will do the hard work for you, but yes, reading the full buffer from the file and writing closer to the beginning is a way to do it if you cannot afford to simplify the work on creating a new file, copy what you want into this file, and then copy the new (temporary) file on top of the old one. I do not exclude that the approach of copying what you want to a new file, and then either transferring the new file instead of the old one, or copying the new one compared to the old one, will be faster than the shuffling process that you describe. If the number of bytes removed is the size of the disk block, rather than 7 bytes, the situation may be different, but probably not. The only drawback is that a more intermediate disk space is required for the copy approach.

For your contouring approach, you will need to use truncate() or ftruncate() to shorten the file to the desired length if you are on a POSIX system. If you do not have truncate() , you will need to do a copy.

Note that opening a file twice will work fine if you try not to compress the file when you open it for writing - using "r+b" with fopen() or avoiding O_TRUNC with open() .

+3
source

You can mmap the file into memory, and then memmove the contents. You will have to trim the file separately.

+4
source

If you are using Linux, then starting with kernel 3.15 you can use

 #include <fcntl.h> int fallocate(int fd, int mode, off_t offset, off_t len); 

with the flag FALLOC_FL_COLLAPSE_RANGE .

http://manpages.ubuntu.com/manpages/disco/en/man2/fallocate.2.html

Note that not all file systems support this, but most modern ones, such as ext4 and xfs, support.

+1
source

Source: https://habr.com/ru/post/903491/


All Articles