Deleting an entry in binary mode without creating a temporary file (C file I / O)

All the codes I have referenced use a temporary file to remove the entry from the file.

Example:

fp=fopen("foo.db","rb");
ft=fopen("temp.db","wb");
//check both files opened or created successfully. Terminate program accordingly 
while(fread(&foo,sizeof(Foo),1,fp))
{
    if(record matched)
    {
        //skip this record
    }
    else
    {
        //write a record in temp file
        fwrite(&foo,sizeof(Foo),1,ft);
    }
}

fclose(fp);
fclose(ft);
remove("foo.db"); //remove original file
rename("temp.db","foo.db"); //rename temp.db to foo.db

      

is this the only way we can implement record deletion?
I can think of overlaying the next recording onto the previous recording.
but how can I complete the last write and mark the end of the file in binary mode?

i also saw this post but no clues

+3


source to share


2 answers


It can be operating system specific. In general, files are a sequence of bytes and you cannot delete a segment of bytes in the middle. You should consider using a library containing indexed files like GDBM or a database like Sqlite (or a real DBMS like PostGreSQL , MongoDb , MariaDb , etc.)

Both GDBM and Sqlite (and often real DBMSs) are built on top of existing filesystems, but provide some high-level abstraction.



In other words, you shouldn't use plain binaries in your case if you want to avoid copying them. As user3121023 commented , you can manage links in a fixed length record and manage a free list, etc. Libraries like GDBM and Sqlite can do something similar as well.

I don't know of a filesystem or operating system that can remove the byte segment in the middle, and there is no POSIX API to do this.

+2


source


You can always overwrite the file in place. At best, you open the file twice, first in "r" mode, then in "w +" mode, you go through the whole file with the algorithm you showed and truncate it at the end: close the read descriptor, truncate on the write descriptor, close the write handle.

If the OS does not allow you to open a file twice, you can do the same with just one file descriptor, using ftell

to mark the last read and write position respectively, and fseek back and forth.



But I think you should not do this. The temporary file not only allows for a simpler algorithm, but also much more reliable. In the event of a crash (break on the console, kill the wrong PID, power outage, thunder, ...) the original file remains intact until the new one is fully written. Easy to recover. But if you try to overwrite in place, if the program breaks in the middle of overwriting, the only file is in an undefined state and all data may be lost, or at least require a much more complicated recovery process. But this is your file and you risk it :-)

+1


source







All Articles