2012-03-20 108 views
6

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

现有的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); 
      } 

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

回答

3

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

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

+0

我不想做任何硬连线,这就是为什么我不在乎实际的默认缓冲区大小。我如何用工厂方法构建FileStream?我仍然被卡住,没有必要的构造函数重载不是吗? – 2012-03-20 16:46:06

+0

您仍然可以使用“if(writeDirectToDisk)...”代码在工厂方法内调用相应的构造函数。所以测试只会在一个地方。并且代码影响将被限制为用“MyFileStreamFactory.Create(...)”替换“新的FileStream(...)” – Joe 2012-03-20 16:59:55

+2

但是不要将缓冲区大小设置为1 – Magnus 2012-03-20 17:04:04

3

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

.Net中不支持WriteThrough。你可以使用非托管的Win API调用,你真的想要那个功能。我只是花了一天的时间来试验它,使用它没有任何优势。这在10多年前并不是真的,高速缓存对速度有明显的影响。

出于兴趣,有人慷慨地写了整个​​库进行API调用,可用here