Sagar
Sagar

Reputation: 228

deleting a record in binary mode without creating a temp file (C file I/O)

All the codes so far I referred uses temp file to delete a record from file.
Ex:

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 deleting record ?
i can think of overlaping next record to previous record.
but how do i terminate last record and mark end of file in binary mode ?
i also saw this post but no clues

Upvotes: 3

Views: 1308

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 148965

You can always rewrite a file in place. At best you open twice the file, first in "r" mode, second in "w+" mode, you scan the whole file with the algorithm you showed and truncate it at the end : close read descriptor, truncate on write descriptor, close write descriptor.

If the OS does not allow you to open the file twice, you can do same thing with only one file descriptor using ftell to note last read and write position respectively and fseek to go back and forth.

But I think you should not want to do that. The temporary file not only allows a simpler algorythm, but also a much more robust one. In case of a failure (break on console, kill of a wrong PID, power outage, thunder, ...) the original file remains untouched until the new one is completely written. It is easy to recover. But if you try to rewrite in place, if the program breaks in the middle of rewriting the only file is in un undetermined state and all data may be lost - or at least will require a much harder recovery process. But it is your file and you take the risk :-)

Upvotes: 1

It could be operating system specific. In general, files are a sequence of bytes, and you cannot remove a segment of bytes in the middle. You should consider using a library providing 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 DBMS) are built above existing file systems, but provide some high-level abstraction.

In other words, you should not use plain binary files in your case, if you want to avoid copying them. As commented by user3121023 you might manage links in your fixed length records and manage a free list, etc... Libraries like GDBM and Sqlite are also able to do something similar.

I know no file system or operating system which is able to remove a segment of bytes in the middle, and there is no POSIX API for this.

Upvotes: 2

Related Questions