Reputation: 1402
So I am using the FileStream
inside XmlReader
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings))
{
reader.close()
}
However, the file feed into the XmlReader
is still in the lock state after the using
scope, weird, I thought the XmlReader
is going to close the FileStream
for me, is it not?
Thanks for help.
Upvotes: 10
Views: 11928
Reputation: 2247
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
}
Upvotes: 17
Reputation: 8827
A few years late but maybe this might help someone...
I tried Eric's method as it seemed like a good solution but I kept getting warning CA2202 when I ran VS code analysis on it.
Near the bottom of CA2202, Microsoft recommends to use the following:
(I slightly modified the it for "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();
}
instead of...
using (Stream stream = new FileStream("file.txt", FileMode.Open))
{
using (XmlReader reader = new XmlReader (stream))
{
// Use the reader object...
}
}
It is much longer but at least it does not throw any warnings.
Upvotes: 0
Reputation: 124692
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();
}
}
Upvotes: 12
Reputation: 1153
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()
Upvotes: 1