2012-11-25 89 views
1

查看來自GAC的'System.IO.File.AppendAllText'代碼,它調用另一個名爲'InternalAppendAllText'的方法,該方法創建一個新的StreamWriter並將內容寫入文件。在.NET中處理對象?

//mscorlib, System.IO 
private static void InternalAppendAllText(string path, string contents, Encoding encoding) 
{ 
    using (StreamWriter writer = new StreamWriter(path, true, encoding)) 
    { 
     writer.Write(contents); 
    } 
} 

我的問題是,如果我做了一個for循環調用System.IO.AppentAllText 5倍例如將StreamWriter的創建5倍,它被初始化每次迭代和處置,或者它只是初始化一次?

例子:

for(int i = 1; i < 4; ++i) 
{ 
    System.IO.File.AppendAllText("a", "a"); 
} 
+0

請輸入密碼。你將如何創建它們?請張貼循環代碼。 – Oded

+0

@TimSchmelter:是的。創建一個名爲'a'的文件是完全合理的。 (它不需要是絕對文件名) –

+0

另一個說明,你的'for'循環和'++ i'技巧是製造錯誤的好方法,特別是如果你的代碼是被他人使用。這是循環5次的極其複雜和不清楚的方式。 –

回答

5

using塊擴展到這個代碼的等效:

StreamWriter writer; 
try 
{ 
    writer = new StreamWriter(path, true, encoding)) 
    writer.Write(contents); 
} 
finally 
{ 
    if (writer != null) 
     writer.Dispose(); 
} 

所以,是,每當一個using塊退出時,對象被設置。每當你重新進入功能,一個新的StreamWriter將被初始化。

但是,請注意,這與垃圾收集器沒有任何關係。 GC會在感覺到它時運行,掃描分配的對象,注意有五個對象沒有連接到任何GC根,並放棄它們。無論您是否稱Dispose或使用using都是如此,它只是GC的工作原理。

什麼using在這裏做的是釋放非託管資源,該對象持有 - 在這種情況下,文件句柄。如果StreamWriter未被銷燬或以其他方式明確關閉,則該文件將保持鎖定狀態,直到您的過程完成或GC決定激活。這是什麼using塊和IDisposable接口是爲了 - 確保您顯式釋放GC不知道的對象。

3

如果你看一下反編譯的代碼流爲以using語句,因此將被清理。它將被全部初始化5次,但只要代碼離開使用語句,它就會被清除。

+0

...因此,您應該追加內存中的文本(StringBuilder!),並且每次大操作只與實際文件交互一次。 – SimpleVar

+0

儘管如此,隱式'Dispose'-call在'using'塊留下時並不會自動強制垃圾回收器進入遊戲。它釋放資源(並防止Garbace收集器首先完成實例),但垃圾收集器將在下一個常規週期中收集五個實例。 – Peit

+0

Nathan,我正在回答代碼如何表現,而不是應該如何使用,因爲我在發佈問題之前發佈了我的答案,以便包含代碼示例,並且因爲代碼應該如何使用的一攬子聲明將需要更多提供的數據。 – taylorjonl