Why is FileStream not closed by XmlReader
You should be able to control this through XmlReaderSettings.CloseInput.
readerSettings.CloseInput = true;
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings))
{
// do work with the reader
}
Or, more concisely if you don't care about other reader settings:
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), new XmlReaderSettings() { CloseInput = true }))
{
// do work with the reader
}
Have you tried this?
using(var stream = new FileStream(archivePath, FileMode.Open))
using(var reader = XmlReader.Create(stream, readerSettings))
{
}
I couldn't find anything in the documentation that explicitly stated that the XmlReader
would call dispose on the underlying stream when it was disposed. Also, I always use it as shown above and I have never encountered a problem.
Browsing through reflector I also find no instances where it calls Dispose()
on the stream when creating a XmlTextReaderImpl
. The XmlTextReaderImpl
does not implement Dispose()
and its Close()
method looks like this:
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();
}
}
You would need to keep track of the FileStream
and the XmlReader
. It's potentially dangerous for the XmlReader
to close the underlying stream. In the case where the FileStream
is used by multiple readers: if one of these readers were to close the stream this would cause the other readers to fail unexpectedly.
It's a bit of a pain since some stream readers and writers will close the underlying stream, while others don't. As a best practice I always close and dispose of the streams I open manually. This also helps mitigate some 'gotchas' with certain streams.
e.g. You need to dispose a GZipStream
before calling .ToArray()