2012-03-20 2 views
6

У нас есть класс ведения журнала, написанный на C#, с использованием .NET 4. Я хочу добавить аргумент конструктора, который при необходимости установит флаг FileOptions.WriteThrough при построении FileStream. Поскольку этот широко используемый библиотечный код я хочу изменить как можно меньше.Конструктор 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.

Кроме этого, вы можете установить размер буфера с помощью Reflector (0x1000).

+0

Я не хочу делать какие-либо жесткие проводки, поэтому мне все равно, каков фактический размер буфера по умолчанию. Как я могу построить FileStream с заводским методом? Я бы все равно застрял без перегрузки конструктора, не так ли? –

+0

Вы все равно можете использовать свой код if (writeDirectToDisk) ... для вызова соответствующего конструктора внутри фабричного метода. Таким образом, тест будет только в одном месте. И влияние кода будет ограничено заменой «нового FileStream (...)» на «MyFileStreamFactory.Create (...)» – Joe

+2

Но не устанавливайте размер буфера на 1 – Magnus

3

Размер буфера по умолчанию можно увидеть в исходном коде .Net, here.

WriteThrough не поддерживается в .Net. Вы можете использовать неуправляемые вызовы Win API, вы действительно хотите эту функциональность. Я просто провел день, экспериментируя с ним, и нет никаких преимуществ для его использования. Это было не так 10 лет назад, когда кеширование оказало заметное влияние на скорость.

Из интереса, кто-то любезно написал всю библиотеку для выполнения вызовов API, доступных here.

Смежные вопросы