プログラム系統備忘録ブログ

記事中のコードは自己責任の下でご自由にどうぞ。

Directory.EnumerateFilesでハマった話

指定ディレクトリ以下の指定拡張子の列挙に便利な System.IO.Directory.EnumerateFiles メソッド。
しかし、searchPattern引数に指定していない拡張子も列挙される場合があります。

2015/11/10追記: MSDN日本語版に改めてアクセスしてみると、解説中の「メモ」の欄にて、この記事で紹介している内容が記載されていました。(ただしラジオボタンの訳文を選択していてもその辺りは英語オンリーです。機械翻訳とは一体。)
というわけで、この記事の存在意義は非常に怪しくなりました。

内容

// "c:/somewhere/" に、 "a.htm" と "b.html"を作成しておく
string dirPath = "c:/somewhere/";

Console.WriteLine(Directory.EnumerateFiles(dirPath, "*.ht").Count());
// -> "0"

Console.WriteLine(Directory.EnumerateFiles(dirPath, "*.htm").Count());
// -> "2"!!!

Console.WriteLine(Directory.EnumerateFiles(dirPath, "*.html").Count());
// -> "1"

説明

MSDN日本語版の説明 には記述がありませんが、
MSDN英語版の説明 には次のような記述があります。

If the specified extension is exactly three characters long, the method returns files with extensions that begin with the specified extension. For example, "*.xls" returns both "book.xls" and "book.xlsx".

上のコードの"*.htm"がまさにこのパターンであり、b.htmlも列挙される仕様です。
どうしても.htmだけを列挙したい場合は、自分でフィルタリングしましょう。

var query = Directory.EnumerateFiles(dirPath, "*.htm")
    .Where(filePath =>
        string.Equals(Path.GetExtension(filePath),
            ".htm",
            StringComparison.OrdinalIgnoreCase));
Console.WriteLine(query.Count());
// -> "1"

教訓

もう全部en-usだけ見ればいいんじゃないかな……。