We've had a problems with FileStream under Mono (different versions, both 2.10.x and 3.0.x). It seems like some internal positioning problem, because instead of overwriting some parts of file, it just appends written data. It is very critical that the amount of bytes written is larger than internal buffer size. I've managed to create small isolated test case that shows both what is necessary for bug to occur and easy workaround for that. But hopefully this will be fixed as this is core functionality.
public class mono_filestream_bug
public void show_time()
const int pos = 1;
const int bufferSize = 128;
var filename = Path.GetTempFileName();
File.WriteAllBytes(filename, new byte[pos + 1]); // init file with zeros
var bytes = new byte[bufferSize + 1 /* THIS IS WHAT MAKES A BIG DIFFERENCE */];
using (var file = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read,
file.Read(new byte[pos], 0, pos); // THIS READ IS CRITICAL, WITHOUT IT EVERYTHING WORKS
Assert.AreEqual(pos, file.Position); // !!! here it says position is correct, but writes at different position !!!
// file.Position = pos; // !!! this fixes test !!!
file.Write(bytes, 0, bytes.Length);
//Assert.AreEqual(pos + bytes.Length, file.Length); -- fails
using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read))
var bb = new byte[bytes.Length];
filestream.Position = pos;
filestream.Read(bb, 0, bb.Length);
We are mixing reading and writing buffer offsets here. We need to split buf_offset to be read and write specific
Any updates on this issue?
The issue in this particular bug is that our first call to Read() will fill the buffer with as much data as possible, in this case 2 bytes.
The reason why file.Position returns 1 instead of 2 is because we are not actually calling the OS seek functionality. We only do that when the Handle has been surfaced (isExposed).
So the right fix, like Marek suggests is to keep two separate poiters.
For reference, this is what the CoreFX does:
After a successful Read the buffer position is updated to the char after the last one read.
The problem as mentioned by Miguel is that the position does not reflect the actual file handle position.
The pull request below fixes this by doing a seek before the write.
Fixed in mono master 7013a709c30ab2f1e1eee56b7aa8d4088e7f555e.
Should be included in Cycle 8, Mono 4.6.