2006年01月29日
川俣晶の縁側ソフトウェア技術雑記total 3710 count

.NET Framework 2.0のXmlWriterSettings.CloseOutputプロパティの既定値はXmlWriter.Createメソッドの引数タイプによって変化する!?

Written By: 川俣 晶連絡先

 .NET Framework 2.0で、XmlWriterを使ってXML文書を書き出す場合には、XmlTextWriterクラスを使わず、XmlWriter.Createメソッドでインスタンスを取得する方法が推奨されています。

 また、このメソッドの引数に指定できるXmlWriterSettingsメソッドは、きめ細かい動作のオプションを指定することを可能としています。

 このうちのXmlWriterSettings.CloseOutputプロパティは、XmlWriterのCloseメソッドを呼んだときに、元になるストリームも閉じるかを指定します。これがfalseの場合、XmlWriterをCloseしたあと、ストリームに何かを書き足すことが可能になります。たとえば、MIMEマルチパートの電子メール本文を書き出す場合などには便利そうですね。

 このプロパティの既定値はfalseです。つまり、Closeメソッドを呼び出しても、元になるストリームは閉じられません。

 以上が前提です。

ファイル名を指定するCreateメソッド §

 XmlWriter.Createメソッドには、引数によって様々なバリエーションがあります。その多くは、XmlWriterSettingsオブジェクトを渡すバリエーションと省略して既定値で使うバリエーションが存在します。

 さて、ここでファイル名のみを指定してそれに対して出力するXmlWriterオブジェクトを生成するバリエーションについて見ていきましょう。

 以下のように使うわけです。

XmlWriter writer = XmlWriter.Create(@"c:\\test.xml");

writer.WriteElementString("test", "data");

writer.Close();

 さて、ここで注意してください。

 このケースでは、明示的にXmlWriterSettingsを渡していません。おそらく、既定値で使われていることが予想されます。

 そして、XmlWriterSettings.CloseOutputプロパティの既定値はfalseです。

 ということは、Closeメソッドを呼び出しても、書き込みに使われるストリームは閉じられません。

 しかし、このプログラムでは、ストリームを閉じるコードが含まれません。というか、そもそもXmlWriterというのは抽象的なクラスなので、ストリームを取得する手段が提供されていません。

 (もちろん、抽象的なクラスのインスタンスは作成できないので、実は取得されているのは非公開クラスらしきSystem.Xml.XmlWellFormedWriterクラスのインスタンス)

 ということは、ファイル名のみを指定するCreateメソッドを使うと永遠にファイルを閉じることができない?

 つまり、ファイル名のみを指定するCreateメソッドには存在意義がない?

実はそうではないらしい §

 実はXmlWriterSettings.CloseOutputプロパティの既定値はfalseだという記述は必ずしも正確ではないようです。

 というのは、実はファイル名のみを指定するCreateメソッドを使うと、このプロパティの値はtrueになってしまうからです。

 検証プログラムで確かめてみました。

検証プログラム §

 .NET Framework 2.0+C#, Visual Studio 2005で作成

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml;

using System.IO;

namespace ConsoleApplication75

{

    class Program

    {

        static void Main(string[] args)

        {

            XmlWriter writer = XmlWriter.Create(@"c:\\test.xml");

            Console.WriteLine("writer.Settings.CloseOutput={0}", 

                writer.Settings.CloseOutput);

            Console.WriteLine(writer.ToString());

            writer.WriteElementString("test", "data");

            writer.Close();

            FileStream stream = new FileStream(@"c:\\test.xml", 

                FileMode.Create);

            XmlWriter writer2 = XmlWriter.Create(stream);

            Console.WriteLine("writer2.Settings.CloseOutput={0}", 

                writer2.Settings.CloseOutput);

            Console.WriteLine(writer2.ToString());

            writer2.WriteElementString("test", "data");

            writer2.Close();

            // あ、streamをCloseするのを忘れているぞ…… (汗

        }

    }

}

実行結果 §

writer.Settings.CloseOutput=True

System.Xml.XmlWellFormedWriter

writer2.Settings.CloseOutput=False

System.Xml.XmlWellFormedWriter

CloseOutputプロパティの値は自動的に補正される §

 結果を見て分かる通り、ファイル名だけを渡した場合と、ストリームだけを渡した場合では、CloseOutputプロパティの値は異なっています。

 つまり、後からストリームを閉じることができないケースについては、自動的にCloseOutputプロパティの値がtrueに補正されるようです。

 つまり、ファイル名のみを指定するCreateメソッドには存在意義はあります。

XmlWellFormedWriterって何だろう? §

 googleさんに質問しても、19件しかヒットしない謎のクラスです。

 Createというファクトリ・メソッドで詳細を隠蔽したのだから触るな……、ということでしょうが、たぶんそれで済まないこともあるでしょう。

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2006年
02月
01日
str1, str2が文字列だとして、if (str1 == str2)と書いてはいけない理由!?
3days 0 count
total 6049 count
【技術雑記】の前のコンテンツ
2006年
01月
28日
サーバと携帯は、100% Pure Javaの可能性を実証する事例であるか!?
3days 0 count
total 3595 count

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

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

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

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

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

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

管理者: 川俣 晶連絡先

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