2003年10月05日
川俣晶の縁側ソフトウェア技術雑記total 2760 count

.NET FrameworkのXML DOMで、Saveメソッドに指定したファイル名をLoadメソッドに指定できない罠

Written By: 川俣 晶連絡先

 まず、クイズを出しましょう。

 .NET Framework 1.1上で動作するC#のサンプルソースです。

 これを実行した場合、どのような結果になるか、当ててみてください。

 C#と.NET Framework 1.1上のXML DOMの知識がある人が対象です。

using System;
using System.Xml;

class DomLoadSave
{
    [STAThread]
    static void Main(string[] args)
    {
        const string filename = @"c:\%AB.xml";
        const string src = "<a/>";
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(src);
        doc.Save(filename);

        XmlDocument doc2 = new XmlDocument();
        doc2.Load(filename);
        Console.WriteLine(doc2.OuterXml);
    }
}

 分かりましたか?

 結果は、以下のような例外です。

'System.IO.FileNotFoundException' のハンドルされていない例外が system.xml.dll で発生しました。

追加情報 : ファイル "c:\«.xml" が見つかりませんでした。

 なぜ、このような結果になるのか、理由が分かりますか?

 これはバグではありません。

 stringを引数に取るLoadメソッドとSaveメソッドは、引数の扱いが異なるというのが、理由です。よく説明を読むと、LoadメソッドはURLだと書いてありますが、Saveメソッドはそう書いてありません。つまり、Loadメソッドは引数をURLとして解釈する際に、ファイルとしてのアクセスも許しているだけの話であって、Windowsのファイル名記述のルールに厳密に合致しているわけではないのです。実際、%記号があると、それはURLエンコードと見なされて解釈されます。これにより、%記号を含む文字列をファイル名として与えると、LoadメソッドとSaveメソッドは異なる対象にアクセスしに行きます。

 これを回避するには、Loadメソッドにファイル名を文字列として渡すのではなく、ファイルをストリームとして開いてからそれを渡すようにすると良いでしょう。

 というバグ取りを現在作業中であったりします…… (涙) うっかり間違えやすいのよね、これ。

追記: DOMだけでなく、XmlReader/Writer系のクラスにも同じ罠があるらしい……。

Facebook

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20031005131739
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.34 (Alpha-Test) Copyright (c) 2004-2018 Pie Dey.Co.,Ltd.