2005年08月11日
川俣晶の縁側ソフトウェア技術雑記total 9166 count

System.IO.Path.Combineメソッドにおいて、ファイル作成に使用できない文字に対して例外を投げる場合と投げない場合がある問題

Written By: 川俣 晶連絡先

 System.IO.Path.Combineメソッドはファイル名を組み立てるための便利なメソッドですが、ファイル名に使用できない文字を含んでいる場合に例外を投げるケースと投げないケースがあることに気付きました。

検証プログラム §

using System;

using System.IO;

class ClassTest

{

    [STAThread]

    static void Main(string[] args)

    {

        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        for( char ch = (char)0x20; ch<(char)0x7f; ch++ )

        {

            string fullpath = "c:\\[" + ch + "].please_delete_me.tmp";

            try

            {

                using( StreamWriter writer = File.CreateText(fullpath) )

                {

                }

            }

            catch( Exception )

            {

            }

            bool flag = false;

            try

            {

                if( File.Exists(fullpath) )

                {

                    File.Delete(fullpath);

                    //Console.WriteLine("deleted {0}",fullpath);

                }

                else

                {

                    flag = true;

                }

            }

            catch( Exception )

            {

                flag = true;

            }

            if( flag )

            {

                sb.Append(ch);

            }

        }

        Console.WriteLine("ファイル作成に使用できなかった文字: {0}",sb.ToString() );

        foreach( char ch in sb.ToString() )

        {

            bool flag = false;

            string text;

            try

            {

                text = "";

                Path.Combine("c:\\",new string(ch,1) );

            }

            catch( Exception ex )

            {

                text = ex.GetType().FullName;

                flag = true;

            }

            Console.WriteLine("Path.Combineにおいて、文字 '{0}' は例外を{1}。{2}",

                ch,flag?"投げます":"投げません",text);

        }

    }

}

実行結果 §

ファイル作成に使用できなかった文字: "*/:<>?\|

Path.Combineにおいて、文字 '"' は例外を投げます。System.ArgumentException

Path.Combineにおいて、文字 '*' は例外を投げません。

Path.Combineにおいて、文字 '/' は例外を投げません。

Path.Combineにおいて、文字 ':' は例外を投げません。

Path.Combineにおいて、文字 '<' は例外を投げます。System.ArgumentException

Path.Combineにおいて、文字 '>' は例外を投げます。System.ArgumentException

Path.Combineにおいて、文字 '?' は例外を投げません。

Path.Combineにおいて、文字 '\' は例外を投げません。

Path.Combineにおいて、文字 '|' は例外を投げます。System.ArgumentException

考察 §

 例外を投げない文字のいくつかは、投げない理由が明確に分かります。

 "*"と"?"については、ワイルドカード指定に使われるので、ファイル作成に使用できないとしても、Combineメソッドで使用するのは正当です。

 "/"と"\"については、実際にはファイル名ではなく、パスの区切り文字として認識されているだけ、ということが推測されます。

 残りは":"ですが、これが良く分かりません。":"はドライブ名などの区切り文字であって、これをファイル名に許す必然性が分かりません。"\\.\C:"のような表記に対応するために許しているとも考えられますが、おそらくドライブ表記が2回出てくるパスは無いような気がするので(根拠無し)、既に先頭に"c:"が付いているパス名にもう1回":"が入るのは不正なパスであるような気がします。しかし、Combineメソッドは例外を投げる対象としていません。

2005年10月17日追記 §

 ":"はNTFSのストリーム名の区切りとして使用される文字なので、許可されることが正当であることをOrator/魔界の仮面弁士さんより指摘して頂きました。詳細は、":"は正当なパスの一部だ! NTFSファイルシステムの複数ストリームをお手軽に体験するを参照願います。

結論 §

 任意の文字を受け付けて、それを引数にCombineメソッドを呼び出すコードの単体テストを書くときには注意しよう。作成できないパスであるにも関わらず、例外を投げるパターンと投げないパターンがあり得るので。双方のケースについて、テストケースを作成することが望ましい。

Facebook

トラックバック一覧

2005年10月17日[.NET]System.IO.Path.Combineでコロンが許可されている理由From: Orator's IO

.NET Framework の「System.IO.Path.Combineメソッド」で使える文字についてです。 川俣さんの技術雑記に、このような検証と考察がありました。 ":"ですが、これが良く分かりません。":"はドライブ名などの区切り文字であって、これをファイル名に許す必然性が分かりま... 続きを読む

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

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

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

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

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

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

管理者: 川俣 晶連絡先

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