FileStream构造函数和默认缓冲区大小

6
我们有一个用于记录日志的C#类,使用的是.NET 4。我想添加一个构造函数参数,该参数在构造FileStream时,可以选择设置FileOptions.WriteThrough标志。由于这是广泛使用的库代码,因此我希望尽可能少地进行更改。 现有的FileStream构造函数调用:
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read);

问题:
在我们的构造函数中,我添加了一个名为writeDirectToDisk的可选布尔参数。我认为我可以这样做:
var fileOptions = writeDirectToDisk ? FileOptions.WriteThrough : FileOptions.None;
_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read, fileOptions);

但是,实际上没有这样的重载!除非我漏掉了什么,否则 FileStream 构造函数接受 FileOptions 参数的唯一可用重载还需要缓冲区大小参数!
我尝试将缓冲区大小设置为零,希望它会使用默认缓冲区大小,但是它抛出了一个异常。
我搜索了一些框架中的静态属性或常量,但找不到指定默认缓冲区大小的内容。
我的问题是:当前阶段,我并不特别关心默认缓冲区大小是多少字节。我只想知道如何在构造函数中添加 FileOptions 参数,并使代码影响最小?
我想知道是否有某个常量或静态变量可以用作缓冲区大小参数,或者我是否错过了某个重载或者是否有更聪明的方法来解决这个问题。我也想知道如果指定了 FileOptions.WriteThrough,则缓冲区大小是否无关紧要,如果是这种情况,我可以这样做:
            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);
            }

但我宁愿不这样做,除非真的没有更优雅的方法。

2个回答

4
默认缓冲区大小可以在.Net的源代码这里看到。
WriteThrough在.Net中不受支持。如果您真的需要该功能,可以使用不受管理的Win API调用。我刚刚尝试了一整天,并没有使用它的优点。10多年前情况并非如此,因为缓存对速度有明显影响。
出于兴趣,有人友好地编写了整个API调用库,可在此处获得。

3
你可以使用自己的工厂方法来构造 FileStream
除此之外,你可以硬编码 Reflector(0x1000)发现的缓冲区大小。

我不想进行任何硬连线,这就是为什么我不关心实际的默认缓冲区大小。我该如何使用工厂方法构建FileStream?如果没有必要的构造函数重载,我还是会被卡住,对吧? - Stephen Kennedy
你仍然可以使用“if (writeDirectToDisk)…”代码在工厂方法内调用适当的构造函数。因此,测试只会出现在一个地方。代码影响将仅限于将“new FileStream(...)”替换为“MyFileStreamFactory.Create(...)”。 - Joe
2
但不要将缓冲区大小设置为1。 - Magnus
Joe:代码已经只存在一个地方了——它在我的日志记录类的构造函数中! :) Magnus,如果我不将缓冲区大小设置为1,那我该设置成什么呢?如果我用反编译工具发现默认值,那我又回到硬编码的问题上了,而我不想这样做,因为那会成为一个重大变化。 - Stephen Kennedy
你不应该害怕将缓冲区大小“硬编码”为0x1000。这是一个很好的缓冲区大小,我看不出有什么问题。 - Magnus
1
五年过去了,DotNetCore 2仍然将4096硬编码为内部但不公开的默认值,在FileStream.cs文件中。 - Chris F Carroll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接