简体   繁体   中英

How do I replace the contents of an existing XML file in C#.NET?

When trying to replace the content of an XML file in C#.NET with a snippet like this:

string file = Path.GetTempFileName(); // pretend this is a real file
string tmpFile = Path.GetTempFileName();

using (var writer = XmlWriter.Create(File.Create(tmpFile)))
{
    writer.WriteStartElement("root");
    for (int i = 0; i < 100; i++)
    {
        writer.WriteElementString("test", null, 
            "All work and no play makes Jack a dull boy");
    }
    writer.WriteEndElement();
}

File.Delete(file);
File.Move(tmpFile, file);

... I get a System.IO.IOException claiming that the file is already opened by another process.

For some reason the XmlWriter class evidently does not dispose the underlying stream for the temporary file. Putting the stream in a "using" clause of its own makes sure the stream is closed correctly. Changing the code to

string file = Path.GetTempFileName(); // pretend this is a real file
string tmpFile = Path.GetTempFileName();

using (var stream = File.Create(tmpFile))
using (var writer = XmlWriter.Create(stream))
{
    writer.WriteStartElement("root");
    for (int i = 0; i < 100; i++)
    {
        writer.WriteElementString("test", null, 
            "All work and no play makes Jack a dull boy");
    }
    writer.WriteEndElement();
}                
File.Delete(file);
File.Move(tmpFile,file);

... makes the IOException disappear and it works as intended.

Using statements can be chained. Slightly modifying your code:

string file = Path.GetTempFileName(); // pretend this is a real file
string tmpFile = Path.GetTempFileName();

using (var stream = File.Create(tmpFile))
using (var writer = XmlWriter.Create(stream))
{
    writer.WriteStartElement("root");
    for (int i = 0; i < 100; i++)
    {
        writer.WriteElementString("test", null, 
            "All work and no play makes Jack a dull boy");
    }
    writer.WriteEndElement();
}                
File.Delete(file);
File.Move(tmpFile,file);

If you're dealing with multiple disposable entities over the same scope (not an uncommon occurrence), this avoids nastily deep nesting. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM