Почему XMLWriter не закрывается? - PullRequest
10 голосов
/ 05 марта 2011

У меня проблемы с закрытием XMLWriter.Я могу успешно написать файл XML один раз, но если я попытаюсь записать его снова (перезаписать), я получу исключение:

"Процесс не может получить доступ к файлу somefile.xml, поскольку он используется другим процессом. "

    Dim settings = New XmlWriterSettings()
    settings.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

Ответы [ 2 ]

15 голосов
/ 05 марта 2011

То, что вам не хватает, это XmlWriterSettings.Вы объявляете это, но не используете его, и когда вы не устанавливаете CloseOutput вручную, по умолчанию используется значение false, что означает, что вывод не закрыт (в данном случае ваш файловый поток).

Чтобы заставить его вести себя так, как вы хотите, измените код следующим образом:

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

Если вам интересно, как это действительно работает внутри, вот метод CloseXmlEncodedRawTextWriterIndent, внутренний XmlWriter, используемый в вашем сценарии.

// 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;
    }
}
2 голосов
/ 05 марта 2011

Я бы ожидал , что это будет файл, а не автор;если бы это был C #, я бы использовал что-то вроде:

using(var file = File.Create("somefile.xml"))
using(var writer = XmlWriter.Create(file))
{
    // write to the writer
}

using (и я полагаю, что VB имеет то же самое, вероятно Using), что избавляет от многих проблем ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...