2012-03-23 84 views
6

所以我使用的是FILESTREAM內xmlreader爲什麼FILESTREAM不是XMLReader的

using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) 
{ 
    reader.close() 
} 

但是,文件送入的XMLReader仍處於鎖定狀態的使用範圍後關閉的,怪異的,我thougt的xmlreader是怎麼回事爲我關閉文件流,不是嗎?

感謝您的幫助。

回答

7

你試過嗎?

using(var stream = new FileStream(archivePath, FileMode.Open)) 
using(var reader = XmlReader.Create(stream, readerSettings)) 
{ 

} 

我找不到明確指出,XmlReader會調用底層的流處理上它被放置在文檔中的任何東西。另外,我總是使用它,如上所示,我從來沒有遇到過問題。

瀏覽反射器當創建XmlTextReaderImpl時,我也沒有發現它在流上調用Dispose()的實例。該XmlTextReaderImpl沒有實現Dispose()及其Close()方法是這樣的:

internal void Close(bool closeInput) 
{ 
    if (this.parsingFunction != ParsingFunction.ReaderClosed) 
    { 
     while (this.InEntity) 
     { 
      this.PopParsingState(); 
     } 
     this.ps.Close(closeInput); 
     this.curNode = NodeData.None; 
     this.parsingFunction = ParsingFunction.ReaderClosed; 
     this.reportedEncoding = null; 
     this.reportedBaseUri = string.Empty; 
     this.readState = ReadState.Closed; 
     this.fullAttrCleanup = false; 
     this.ResetAttributes(); 
    } 
} 
+1

說實話,沒有。我認爲XmlReader就像StreamReader,一旦完成就會關閉內部流。使用兩個使用語句只是有點笨拙。 – 2012-03-23 19:01:54

+1

軼事,但我看到的大多數例子都使用了兩個「使用」的例子。 – 2012-03-23 19:04:03

+1

@TOMMYWANG:那麼你可能會這樣想,但是我找不到代碼中的任何地方(使用反射器),其中'XmlTextReaderImpl'(這是'XmlReader.Create()'實際返回的內容)處理該流。如果它確實關閉了流,那麼當爲多個閱讀器使用一個流時會遇到問題(如果我想讓流保持活動狀態,爲什麼讀者應該決定我不能?),因此需要採取安全的做法沒有。我不同意它是「笨拙的」,但「笨拙」比「破碎」更好。 – 2012-03-23 19:05:06

1

您將需要跟蹤FileStreamXmlReader的。 XmlReader關閉底層流可能會有潛在危險。在多個閱讀器使用FileStream的情況下:如果其中一個閱讀器關閉該流,則會導致其他閱讀器意外失敗。

這有點痛苦,因爲一些流讀者和作者會關閉底層流,而另一些則不會。作爲最佳做法,我總是關閉並處理手動打開的流。這也有助於緩解某些流的一些「陷阱」。
例如You need to dispose a GZipStream before calling .ToArray()

9

你應該可以通過XmlReaderSettings.CloseInput來控制它。

readerSettings.CloseInput = true; 
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) 
{ 
    // do work with the reader 
} 

或者,更簡明,如果你不關心其他閱讀器設置:

using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), new XmlReaderSettings() { CloseInput = true })) 
{ 
    // do work with the reader 
} 
+1

好的答案,這阻止FxCop抱怨多處置,如果你設置CloseInput = false,這很煩人。 – briantyler 2014-03-16 22:46:00

+0

這裏不是reader.close()語句冗餘,因爲退出using語句會調用Dispose()並調用Close()? – Kent 2018-01-03 05:07:34

0

幾年晚,但也許這會幫助別人......

我試過Eric的方法因爲它似乎是一個很好的解決方案,但當我運行VS代碼分析時,我一直收到警告CA2202

CA2202底部,微軟建議使用以下方法:(我稍微修改了它 「的XmlReader」)

Stream stream = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.Open); 
    using (XmlReader reader = new XmlReader (stream)) 
    { 
     stream = null; 
     // Use the reader object... 
    } 
} 
finally 
{ 
    if(stream != null) 
     stream.Dispose(); 
} 

的,而不是...

using (Stream stream = new FileStream("file.txt", FileMode.Open)) 
{ 
    using (XmlReader reader = new XmlReader (stream)) 
    { 
     // Use the reader object... 
    } 
} 

它要長得多,但至少不會引發任何警告。

相關問題