It depends on whether you have fixed size records or varying size records.
Varying size records
Well, what you need to do is move up all the content of the file following the record you want to get rid of, to overwrite the part you want to remove, and then truncate the file. This is slightly hard to do in-place (ie. inside the same file), as you can only read enough data to avoid overwriting the rest of the file each iteration of your move-up-loop.
A simpler method that will create a new file from the old is as follows:
- Make a note of the position of the stream before you deserialize an item
- If the item match, make a note of the position of the stream as it is now (the two positions now delineate the area of the file where the record you want to get rid of is)
- Create a new file, and first copy, from the start, the same number of bytes as the first position, from the old stream (the one you found the record in), to the new stream
- Position the old stream at the position you noted after the record you found, and copy everything that you can find from there on out into the new stream
This will create a new file with the same content as the old, except that you skip the record you want to get rid of.
If you can loop through all the records and simply determine if you want to keep it or not, here's an even simpler method:
- Open up a new stream
- Deserialize an item from the old stream
- If you want to keep it, serialize it back into the new stream
- And so on for the rest of the items.
Fixed size records
Simply read the last record of the file, position the file back to the position of the record you want to remove, and overwrite it with the contents of the last record that you just read, then truncate the file just before the last record of the file.