Reputation: 20404
I'm writing a data storage library that writes records to specific positions in a binary file. For each written record, its byte position in the file is determined, the file stream is seeked to that position and then the record bytes are written.
Now I'm observing strange behaviour where other data is written than passed to the write call. Some records are just duplicated (overwrites adjacent record), others are plain garbage when reading again. The bug occurs very rarely but still damages some data every now and then which is unacceptable. Maybe it's my seeking and flushing that's not correct here. Since buffer/flush issues are not reproducible by nature, I can't write a test case to identify the issue (yet).
The code goes like this:
// Init
var file = File.Open(fileName, FileMode.CreateNew);
var writer = new BinaryWriter(file, Encoding.UTF8, leaveOpen: true);
// For each record to write, in random order
long index = GetIndex(record.Time);
long newPosition = headerLength + index * recordLength;
file.Seek(newPosition, SeekOrigin.Begin);
writer.Write((byte)record.Flags);
writer.Write((double)record.Value);
// Closing
writer.Close();
file.Close();
So I do a seek for each record, but no flush. I want to keep disk write operations to a minimum. The caller can choose to regularly flush the file.
Could a seek destroy my previously written data if it's still buffered somewhere? The seek call uses some strategy internally and I can't follow that path. No idea what it's doing internally.
Do I need to call Flush() explicitly before any Seek()? Or does the FileStream know which data needs to go where?
Upvotes: 0
Views: 40