2012-03-23 9 views
6

So verwende ich das Filestream innerhalb xmlreaderWarum Filestream nicht von xmlreader geschlossen

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

jedoch die Datei-Feed in die xmlreader noch im verriegelten Zustand nach der Verwendung von Rahmen, sonderbar, thougt ich die xmlreader wird um den filestream für mich zu schließen, ist es nicht?

Danke für Hilfe.

Antwort

7

Haben Sie das versucht?

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

} 

Ich konnte nichts in der Dokumentation, die ausdrücklich erklärt, dass die XmlReader fordern den zugrunde liegenden Stream entsorgen würde, wenn er angeordnet wurde. Außerdem verwende ich es immer wie oben gezeigt und ich habe noch nie ein Problem festgestellt.

Durchsuchen des Reflektors Ich finde auch keine Instanzen, wo es Dispose() auf dem Stream beim Erstellen eines XmlTextReaderImpl ruft. Die XmlTextReaderImpl nicht implementiert Dispose() und seine Close() Methode sieht wie folgt aus:

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

um ehrlich zu sein, nein. Ich dachte, XmlReader ist wie StreamReader, schließt den inneren Stream sobald es fertig ist. Verwenden Sie zwei Using-Anweisung ist nur ein bisschen ungeschickt. –

+1

Anekdotisch, aber die meisten Beispiele, die ich sehe, verwenden die zwei 'using's. –

+1

@TOMMYWANG: Nun, Sie denken vielleicht, aber ich kann nirgends im Code finden (unter Verwendung von Reflektor), wo 'XmlTextReaderImpl' (was' XmlReader.Create() 'tatsächlich zurückgibt) über den Stream verfügt. Wenn es den Stream schließen würde, würden Sie Probleme bekommen, wenn Sie einen Stream für mehrere Leser verwenden (was ist, wenn ich den Stream am Leben halten will? Warum sollte der Leser entscheiden, dass ich das nicht kann?), So dass es die sichere Vorgehensweise erfordert nichts. Ich stimme nicht zu, dass es "ungeschickt" ist, aber "tollpatschig" ist besser als "kaputt". –

1

Sie würden Spur des FileStream und der XmlReader halten müssen. Es ist potenziell gefährlich für die XmlReader, den zugrunde liegenden Stream zu schließen. In dem Fall, in dem die von mehreren Lesern verwendet wird: Wenn einer dieser Leser den Stream schließen würde, würde dies dazu führen, dass die anderen Lesegeräte unerwartet ausfallen.

Es ist ein bisschen schmerzhaft, da einige Stream-Reader und Writer den zugrunde liegenden Stream schließen, andere nicht. Als Best Practice schließe und verlasse ich immer die Streams, die ich manuell öffne. Dies hilft auch, einige "Fehler" mit bestimmten Streams zu mildern.
z.B. You need to dispose a GZipStream before calling .ToArray()

9

Sie sollten in der Lage sein, dies über XmlReaderSettings.CloseInput zu steuern.

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

Oder prägnanter, wenn Sie nicht über andere Leser Einstellungen kümmern:

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

Gute Antwort, das hält FxCop davon ab, sich über Mehrfachveräußerungen zu beschweren setze CloseInput = false, was mich nervte – briantyler

+0

Ist die reader.close() - Anweisung hier nicht redundant, da das Beenden der using-Anweisung Dispose() aufruft und das Close() aufruft? – Kent

0

Ein paar Jahre zu spät, aber vielleicht könnte dies jemand helfen ...

I Erics Methode versucht wie es schien eine gute Lösung, aber ich bekam immer Warnung CA2202, wenn ich VS-Code-Analyse darauf ausgeführt.

In der Nähe der Unterseite des CA2202, empfiehlt Microsoft die folgenden zu verwenden: (. I leicht die es für "XmlReader" geändert)

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(); 
} 

statt ...

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

Es ist viel länger, aber es gibt keine Warnungen.

Verwandte Themen