2010-04-12 57 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); 
    } 
} 

編輯:
這是一個選擇,如果你想將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()是不必要的 - 它是需要刷新的「上面」流,這在現在已經完成了。 – 2010-04-12 10:58:07

+0

@danbystrom,很高興幫助。你是對的,StreamWriter會在它處理之前刷新。但Seek可能很有用。 – 2010-04-12 11:10:38

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的反彙編以檢查在這兩種方法中實際完成的操作。

無論如何,使用上述子類的結果是,當關閉streamwriter時,基礎流將被關閉,但不會丟棄。

+0

夠了!關閉不被調用,並在處置中我必須添加一個 Flush()。然後它看起來像微風一樣工作 – 2010-04-12 10:41:49

+0

只需從Dispose覆蓋中調用base.Dispose(false)即可。它將正確處置任何StreamWriter內部資源,同時保持基礎流保持不變(根據定義,因爲它是受管資源)。 – 2012-09-27 11:02:55