开发者

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜