2012-03-20 109 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