We have a logging class written in C# using .NET 4. I want to add a constructor argument which will optionally set the FileOptions.WriteThrough flag when constructing a FileStream. As this is widely used library code I want to change as little as possible.
Existing FileStream constructor call:
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
The problem:
To our constructor I have added an optional bool argument named writeDirectToDisk. I thought I'd then be able to do something like this:
var fileOptions = writeDirectToDisk ? FileOptions.WriteThrough : FileOptions.None;
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read, fileOptions);
but no, there's no such overload! Unless I'm missing something the only overloads available for FileStream's constructor which accept a FileOptions argument also require a buffer size argument!
What I've tried:
I've tried setting buffer size to zero hoping that would use the default buffer size but no it throws an exception.
I've searched for and can't find some static property or constant in the framework which specifies what the default buffer size is.
My question:
I'm not at this stage particularly bothered about how many bytes the default buffer size is. I just want to know how I can add the FileOptions argument to the constructor with as little code impact as possible?
I'm wondering if there is some constant or static var which I've missed that I could use as the buffer size argument or if there's an overload I've missed or indeed if there's some smarter way to do this. I'm also wondering if the buffer size is irrelevant when FileOptions.WriteThrough is specified in which case I could do this:
if (writeDirectToDisk)
{
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read, 1, FileOptions.WriteThrough); // 1 is the smallest value allowed, it will actually be 8 bytes
}
else
{
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
}
but I'd rather not unless there's really no more elegant way.
The default buffer size can be seen in .Net's source code, here.
WriteThrough is not supported in .Net. You can use unmanaged Win API calls is you really want that functionality. I just spent a day experimenting with it, and there are no advantages to using it. This was not true 10+ years ago, where the caching had a noticeable effect on speed.
Out of interest, someone kindly wrote the whole library for doing the API calls, available here.
You could use your own factory method to construct the FileStream
.
Other than that, you could hardwire the buffer size discovered using Reflector (0x1000).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With