2

C#.NET で XML ファイルのコンテンツを次のようなスニペットに置き換えようとすると、次のようになります。

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);

... ファイルが別のプロセスによって既に開かれていることを示す System.IO.IOException が発生します。

4

2 に答える 2

7

何らかの理由で、XmlWriter クラスは明らかに、一時ファイルの基になるストリームを破棄しません。ストリームを独自の「using」句に入れると、ストリームが正しく閉じられるようになります。コードを次のように変更します

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);

... IOException が消え、意図したとおりに動作します。

于 2009-01-15T11:15:51.890 に答える
4

using ステートメントは連鎖できます。コードを少し変更します。

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);

同じスコープで複数の使い捨てエンティティを扱っている場合 (珍しいことではありません)、これにより厄介な深いネストが回避されます。:)

于 2009-01-15T15:13:06.420 に答える