Why is the XMLWriter Not Closing?
I am having some trouble with the XMLWriter not closing. I can successfully write the XML file once but if I try to write it again (overwrite) I get the exception:
"The process cannot access the file 'somefile.xml' because it is being used by another process."
Dim settings = New XmlWriterSettings()
sett开发者_StackOverflow社区ings.Indent = True
settings.IndentChars = " "
settings.NewLineOnAttributes = True
Try
Dim writer As XmlWriter = XmlWriter.Create(System.IO.File.Create("somefile.xml"))
writer.WriteStartDocument(True)
writer.WriteStartElement("root")
For rowCounter As Integer = ds.Tables(0).Rows.Count - 1 To 0 Step -1
writer.WriteStartElement("someelement")
writer.WriteElementString("col0", ds.Tables(0).Rows(rowCounter)(0).ToString)
writer.WriteElementString("col1", ds.Tables(0).Rows(rowCounter)(1).ToString)
writer.WriteElementString("col2", ds.Tables(0).Rows(rowCounter)(2).ToString)
writer.WriteElementString("col3", ds.Tables(0).Rows(rowCounter)(3).ToString)
writer.WriteElementString("col4", ds.Tables(0).Rows(rowCounter)(4).ToString)
writer.WriteElementString("col5", ds.Tables(0).Rows(rowCounter)(5).ToString)
writer.WriteElementString("col6", ds.Tables(0).Rows(rowCounter)(6).ToString)
writer.WriteElementString("col7", ds.Tables(0).Rows(rowCounter)(7).ToString)
writer.WriteEndElement()
Next
writer.WriteEndElement()
writer.WriteEndDocument()
Catch ex As System.IO.IOException
MessageBox.Show(ex.Message)
Finally
writer.Flush()
writer.Close()
End Try
What you are missing, is XmlWriterSettings
. You declare it, but you don't use it, and when you don't set CloseOutput
by hand, the default is false, which means that the output is not closed (in this case your filestream).
To have it behave the way you want it, change your code like this:
Dim settings = New XmlWriterSettings()
settings.Indent = True
settings.IndentChars = " "
settings.NewLineOnAttributes = True
settings.CloseOutput = True ' <<<< the change '
Using writer As XmlWriter = XmlWriter.Create(System.IO.File.Create("somefile.xml"), settings)
'.... etc'
End Using
In case you're wondering about how this really works internally, here's the Close
method of XmlEncodedRawTextWriterIndent, the internal XmlWriter used in your scenario.
// courtesy of Red Gate's Reflector
public override void Close()
{
this.FlushBuffer();
this.FlushEncoder();
this.writeToNull = true;
if (this.stream != null)
{
this.stream.Flush();
if (this.closeOutput) //this flag is set to settings.CloseOutput
{
this.stream.Close();
}
this.stream = null;
}
else if (this.writer != null)
{
this.writer.Flush();
if (this.closeOutput)
{
this.writer.Close();
}
this.writer = null;
}
}
I would expect this to be the file rather than the writer; if this were C#, I would use something like:
using(var file = File.Create("somefile.xml"))
using(var writer = XmlWriter.Create(file))
{
// write to the writer
}
using
(and I believe VB has the same thing, probably Using
) saves a lot of pain here...
精彩评论