【问题标题】:FileStream constructor and default buffer sizeFileStream 构造函数和默认缓冲区大小
【发布时间】:2012-04-05 04:09:17
【问题描述】:

我们有一个使用 .NET 4 用 C# 编写的日志记录类。我想添加一个构造函数参数,在构造 FileStream 时可以选择设置 FileOptions.WriteThrough 标志。由于这是广泛使用的库代码,因此我希望尽可能少地更改。

现有的 FileStream 构造函数调用:

_stream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.Read);

问题:

在我们的构造函数中,我添加了一个名为 writeDirectToDisk 的可选 bool 参数。我以为我可以做这样的事情:

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);
            }

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

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    默认缓冲区大小可以在.Net的源代码中看到,here

    .Net 不支持 WriteThrough。您可以使用非托管 Win API 调用是您真正想要的功能。我只是花了一天的时间试验它,使用它并没有任何优势。 10 多年前情况并非如此,当时缓存对速度有显着影响。

    出于兴趣,有人为进行 API 调用编写了整个库,可用 here

    【讨论】:

      【解决方案2】:

      您可以使用自己的工厂方法来构造FileStream

      除此之外,您可以硬连线使用反射器 (0x1000) 发现的缓冲区大小。

      【讨论】:

      • 我不想做任何硬接线,这就是为什么我不在乎实际的默认缓冲区大小是多少。我将如何使用工厂方法构造 FileStream?如果没有必要的构造函数重载,我仍然会被卡住,不是吗?
      • 您仍然可以使用“if (writeDirectToDisk)...”代码在工厂方法中调用适当的构造函数。所以测试只会在一个地方进行。并且代码影响将仅限于将“new FileStream(...)”替换为“MyFileStreamFactory.Create(...)”
      • 但不要将缓冲区大小设置为 1
      • Joe:代码已经在一个地方——它在我的日志类的构造函数中! :) Magnus,如果我不将缓冲区大小设置为 1,我应该将其设置为什么?如果我发现 Reflector 的默认值是什么,我将再次回到硬编码,我不想这样做,因为这将成为一个重大变化。
      • 五年过去了,dotnetcore 2 在 FileStream.cs 中仍然有 4096 硬连线作为内部但不是公共默认值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      • 2013-08-14
      • 2015-06-07
      • 2016-03-24
      相关资源
      最近更新 更多