Избегайте утилизации базового потока
Я пытаюсь высмеять некоторые файловые операции. В "реальном" объекте у меня есть:
StreamWriter createFile( string name )
{
return new StreamWriter( Path.Combine( _outFolder, name ), false, Encoding.UTF8 ) );
}
В макетном объекте я хотел бы иметь:
StreamWriter createFile( string name )
{
var ms = new MemoryStream();
_files.Add( Path.Combine( _outFolder, name ), ms );
return new StreamWriter( ms, Encoding.UTF8 ) );
}
где _files - это словарь для хранения созданных файлов для последующей проверки.
Однако, когда потребитель закрывает StreamWriter, он также предоставляет MeamoryStream...: - (
Любые мысли о том, как преследовать это?
Ответы
Ответ 1
Если вы подклассифицируете MemoryStream, это будет работать, но вы должны вызвать метод ManualDispose, чтобы закрыть базовый поток.
Я не уверен, но я думаю, что этот объект будет собираться с мусором, когда он выходит за рамки.
public sealed class ManualMemoryStream : MemoryStream
{
protected override void Dispose(bool disposing)
{
}
public void ManualDispose()
{
base.Dispose(true);
}
}
Edit:
Это альтернатива, если вы хотите, чтобы MemoryStream был очищен и готов к чтению сверху.
public sealed class ManualMemoryStream : MemoryStream
{
protected override void Dispose(bool disposing)
{
Flush();
Seek(0, SeekOrigin.Begin);
}
public void ManualDispose()
{
base.Dispose(true);
}
}
Ответ 2
Характер StreamWriter заключается в том, чтобы избавиться от базового потока, когда он сам настроен. Однако, создавая (и возвращая) подкласс StreamWriter (я собираюсь назвать его LeakyStreamWriter), вы должны быть в состоянии предотвратить это поведение по умолчанию.
public class LeakyStreamWriter : StreamWriter
{
public override void Close()
{
BaseStream.Close(); //close, but do not dispose
}
protected override void Dispose(bool disposing)
{
//do nothing here
}
}
Обратите внимание, что я исхожу из предположения, что StreamWriter не имеет других компонентов для размещения, кроме базового потока, вы можете проверить разборку StreamWriter, чтобы проверить, что на самом деле выполняется в этих двух методах.
В любом случае результат использования вышеуказанного подкласса заключается в том, что базовый поток будет закрыт, но не будет удален, когда потоковик будет закрыт.