2010-04-12 2 views
2

Я пытаюсь высмеять некоторые файловые операции. В «реальном» объекте у меня есть:Избегайте утилизации базового потока

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 ... :-(

Любые мысли о том, как проводить это?

ответ

4

Если вы подклассифицируете 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); 
    } 
} 
+0

Мне это нравится! Но Flush() не нужен - поток «выше» нуждается в очистке, который уже был сделан на этом этапе. –

+0

@danbystrom, рад помочь. Вы правы, StreamWriter будет заподлицо до того, как он будет удален. Но Иск может быть полезным. –

3

Характер 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, чтобы проверить, что на самом деле выполняется этими двумя методами.

В любом случае результатом использования вышеуказанного подкласса является то, что базовый поток будет закрыт, но не будет удален, когда потоковый блок будет закрыт.

+0

достаточно близко! Закрыть не вызывается и в Dispose я должен добавить Flush(). Затем, похоже, работает как бриз –

+0

Просто позвоните в base.Dispose (false) из параметра Dispose override. Он будет правильно распоряжаться любыми внутренними ресурсами StreamWriter, оставив непокрытый базовый поток (по определению, поскольку это управляемый ресурс). –

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