ディレクトリ名に不正な文字が存在するか調べる際に
Path.GetInvalidPathChars
と Path.GetInvalidFileNameChars
のどちらを使えばいいのか、
そしてどのような違いがあるのか分からなくなったので備忘録。
実際に返してくる配列を見てみる
コンソールアプリを使用して、次のようなコードを実行する。
using System;
using System.IO;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Path.GetInvalidPathChars()");
foreach (char invalidChar in Path.GetInvalidPathChars())
{
Console.WriteLine(invalidChar);
}
Console.WriteLine("Path.GetInvalidFileNameChars()");
foreach (char invalidChar in Path.GetInvalidFileNameChars())
{
Console.WriteLine(invalidChar);
}
Console.ReadKey();
}
}
}
結果はいくつか読めない(null文字など(?))文字も出力されたので、見ることのできた文字をここに羅列しよう。
Path.GetInvalidPathChars()
"
<
>
|
Path.GetInvalidFileNameChars()
"
<
>
|
:
*
?
\
/
ここから分かるのは、Path.GetInvalidFileNameChars
は名前にFileName
があるが、ディレクトリの命名に使用できない文字の一覧でもある。
また、Path.GetInvalidFileNameChars
はPath.GetInvalidPathChars
を含んでいると断言しても問題なさそうだが、念のため調べる。
(文字コードで見る)実際に返す値
こーど (一部省略)
static void Main(string[] args)
{
Console.WriteLine("Path.GetInvalidPathChars()");
foreach (char invalidChar in Path.GetInvalidPathChars())
{
- Console.WriteLine(invalidChar);
+ Console.WriteLine((int)invalidChar);
}
Console.WriteLine("Path.GetInvalidFileNameChars()");
foreach (char invalidChar in Path.GetInvalidFileNameChars())
{
- Console.WriteLine(invalidChar);
+ Console.WriteLine((int)invalidChar);
}
Console.ReadKey();
}
結果 (連番は省略)
Path.GetInvalidPathChars()
34
60
62
124
0 ~ 31
Path.GetInvalidFileNameChars()
34
60
62
124
0 ~ 31
58
42
63
92
47
Path.GetInvalidFileNameChars
はPath.GetInvalidPathChars
を含んでいる。
まとめ
-
Path.GetInvalidFileNameChars()
はPath.GetInvalidPathChars()
を含んでいる。 -
Path.GetInvalidFileNameChars()
のみ:
、*
、?
、\
、/
を含んでいる。 - 上記2つより、
Path.GetInvalidPathChars()
とPath.GetInvalidFileNameChars()
の違いは:
、*
、?
、\
、/
を含んでいるかいないか。 - ディレクトリ名を調べたい時も
Path.GetInvalidFileNameChars()
を使用しなければならない。
ちなみに...
ファイル/ディレクトリ名は他にも、
-
CON
、PRN
、AUX
、NUL
、COM1 ~ COM9
(連番)、LPT1 ~ LPT9
(連番)と言う名前 (拡張子除く) - 長すぎる
であるとエラーが発生する。(もちろんファイル/ディレクトリが既に存在する/存在しないも)
正直めんどくさいので、一番手っ取り早い(?)方法は次にようになる。
public bool IsInvalidFileName(string path, bool isDir = false)
{
bool anyError = false;
try
{
if (isDir)
{
Directory.CreateDirectory(path);
}
else
{
File.WriteAllText(path, "");
}
}
catch (Exception ex)
{
anyError = true;
// エラーメッセージ取得など
}
/* もしくは
catch (ArgumentException) { }
catch (PathTooLongException) { }
catch (NotSupportedException) { }
みたいな */
// 確認だけなら消したり...?
return anyError;
}
作って確認してしまえば絶対大丈夫