質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.78%

  • C#

    3869questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

System.IO.Directory.GetFiles の挙動について

解決済

回答 4

投稿 2017/01/26 20:19 ・編集 2017/01/27 00:03

  • 評価
  • クリップ 3
  • VIEW 938

Nakashige

score 8

【開発環境】
Windoes10(x64)
Visual Studio 2013

現在、任意のフォルダーに対してファイル一覧を取得する関数を作成しています。
ここで問題が発生しました。

以下のようなファイル構成と仮定します。

■Cドライブ
c:\tmp\sample.xls
c:\tmp\sample.xlsx

■Dドライブ
d:\tmp\sample.xls
d:\tmp\sample.xlsx

ここで、下記コードを実行すると、取得できるファイルが異なります。

string path1 = @"c:\tmp";
Directory.GetFiles(path1, "*.xls"); // sample.xls, sample.xlsx どちらも取得できる

string path2 = @"d:\tmp";
Directory.GetFiles(path2, "*.xls"); // sample.xls のみ取得できる

Directory.GetFiles メソッド
MSDN を参照すると、必ず xls, xlsx どちらのファイルも取得できると考えています。

以下、MSDN(Directory.GetFiles)のメモを引用

アスタリスクのワイルドカード文字を使用する場合、 searchPattern 「*.txt」など、指定した拡張子の文字数影響を与えます検索次ようにします。
指定された拡張機能が 3 文字の場合は、指定した拡張子が始まる拡張子を持つファイルを返します。 
たとえば、「*.xls」には、"book.xls"と"book.xlsx"両方が返されます。
その他のすべてのケースでは、メソッドは、指定された拡張機能を正確に一致するファイルを返します。
たとえば、"* .ai"が"file.ai"、"file.aif"を返します。
疑問符 () のワイルドカード文字を使用すると、このメソッドは、指定されたファイル拡張子に一致するファイルのみを返します。
たとえば、ディレクトリの検索パターンに 2 つのファイル、"file1.txt"および"file1.txtother"指定された"ファイル? です。txt"は最初のファイルだけを返し、"file*.txt"の検索パターンには、両方のファイルが返されます。

なぜDドライブ内のフォルダーに対しては xlsx が取得できないのでしょうか?

ご存じの方がいらっしゃいましたら、ご回答いただけますようお願いいたします。

【追記】
検証情報をいただいたため、追記します。

・Windows7環境では現象が発生しません
・ドライブはいずれもNTFSです
・Windows10、及びWindowsServer2016で現象を確認しています。

以上

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+10

どうやら、"8.3形式のファイル名を生成するか否か"の設定が影響するようですね。

昔のOSではファイル名はドットの前が8文字まで、ドットの後が3文字まで、という制限がありました。
これを"8.3形式"と呼んだりします。
その名残で、今のWindowsでも内部的に8.3形式の名前を持つことがあり、
dirコマンドに/xオプションをつけると8.3形式の名前が確認できます。

C:\tmp>dir /x
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 857D-9700 です

 C:\tmp のディレクトリ

2017/01/27  13:41    <DIR>                       .
2017/01/27  13:41    <DIR>                       ..
2017/01/27  13:02            22,528              sample.xls
2017/01/27  13:01             6,265 SAMPLE~1.XLS sample.xlsx
               2 個のファイル              28,793 バイト
               2 個のディレクトリ  683,712,335,872 バイトの空き領域

C:\tmp>d:

D:\>cd tmp

D:\tmp>dir /x
 ドライブ D のボリューム ラベルは vhd です
 ボリューム シリアル番号は F4D3-1360 です

 D:\tmp のディレクトリ

2017/01/27  13:28    <DIR>                       .
2017/01/27  13:28    <DIR>                       ..
2017/01/27  13:02            22,528              sample.xls
2017/01/27  13:01             6,265              sample.xlsx
               2 個のファイル              28,793 バイト
               2 個のディレクトリ   1,045,876,736 バイトの空き領域

8.3形式のファイル名を生成するか否かは、ボリュームごとに設定することができます(Windows 7以降)。
たとえば私の環境の場合、Cは有効、VHDでNTFSにしたDは無効でした。

C:\WINDOWS\system32>fsutil behavior query disable8dot3 c:
ボリュームの状態は 0 です (8dot3 名の作成は有効です)。
レジストリの状態は 2 です (ボリューム単位で設定します - 既定値)。

上の 2 つの設定に基づいて、8dot3 名の作成は c: で有効です

C:\WINDOWS\system32>fsutil behavior query disable8dot3 d:
ボリュームの状態は 1 です (8dot3 名の作成は無効です)。
レジストリの状態は 2 です (ボリューム単位で設定します - 既定値)。

上の 2 つの設定に基づいて、8dot3 名の作成は d: で無効です

System.IO.Directory.GetFilesメソッドは、この8.3形式の名前も検索対象に含むようです。
そのため、8.3形式が有効なCでは2ファイルが取得され、
8.3形式が無効なDでは1ファイルのみ取得された、
ということのようです。

以上、まとめますと、

  • 8.3形式が有効なボリュームかどうかによってSystem.IO.Directory.GetFilesメソッドの挙動は異なる
  • 8.3形式が有効かどうかはfsutil behavior query disable8dot3で確認できる

ということになります。

参考:
8.3形式の短いファイル名を生成しないようにする - @IT

投稿 2017/01/27 13:50

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/27 18:24

    ありがとうございます!
    解決しました!!

    キャンセル

  • 2017/01/27 20:26

    "8.3形式のファイル名を生成するか否かは、ボリュームごとに設定することができます(Windows 7以降)。 "
    なんて、全く初耳でした!
    ファイルシステムまでは疑えたのですが、上記の様な設定が有るとは全く想像できませんでした。
    8.3なども検索していたのですが見つけられませんでした。超参考になりました。

    キャンセル

  • 2017/01/27 21:46

    本当にありがとうございました。
    hikochang さんの「FAT32とNTFSで動きが違う」も勉強になりましたが、8.3形式もとても勉強になりました。
    社内でも共有しておきます!!

    キャンセル

+2

試してませんがFAT32とNTFSとで動作が違ったかも知れません。Dドライブは外付けのメモリか何かですよね?一度NTFSで確認して見ては?

投稿 2017/01/26 23:44

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/26 23:52

    回答ありがとうございます。
    こちらの検証PCはすべてNTFSでした。
    逆にFAT32環境では検証できておりません。

    補足ですが
    ・Cドライブ、Dドライブが物理的に別れている場合
    ・Cドライブをパーティションで区切ってDドライブを作成した場合
    Windows10の場合では、上記のどちらでも現象が発生しております。

    キャンセル

  • 2017/01/27 00:01

    Dドライブがダメということですか?
    Eドライブにした場合は?
    拡張子 *.AAA と*.AAAA でも発生しますか?

    Directory.GetFilesはFAT32とNTFSで動きが違うので、当たりかと思ってましたが、、、残念です

    キャンセル

  • 2017/01/27 00:25

    Eドライブでも現象が発生していました。。
    Cドライブだけが正常に動作しているようです。

    >*.AAA, *.AAAA
    検証してみましたが、現象が発生していました。

    FAT32、NTFSで動作が異なることは知らなかったです。
    勉強になりました、ありがとうございます m(_ _)m

    キャンセル

  • 2017/01/27 00:40

    *.* などを指定して全てを列挙した場合はどうでしょうか?

    キャンセル

  • 2017/01/27 00:56

    すみません、今日はもう試せる環境ではないため、また明日改めて検証させていただきます。
    お付き合いいただきありがとうございます。

    キャンセル

  • 2017/01/27 08:56

    *.* の指定ではすべてのファイルが正常に列挙されます。
    MSDNにもあるように、ワイルドカード+3文字拡張子の指定時の特別な挙動と認識しています。

    ただ、今回私が作成したいプログラムは「*.xls」「*.xlsx」を列挙するプログラムです。
    対象フォルダーによって動作が異なるので、実装者がそれを飲み込んだ上で実装しなければならないのかな、と疑問に思い投稿しました。

    キャンセル

  • 2017/01/27 18:58

    いろいろとアドバイスいただきありがとうございます。
    無事解決することができました。

    キャンセル

+1

回答にはなっていませんが失礼します。

同じ環境が準備できなかった為、
・Windows7 64bit
・.Net v4.0.30319(64bit と 32bit 両方でコンパイル)
の環境にて同等のソースを書いて実行してみたところ、意図したとおりの結果となりました。

私もこのメソッドを利用したツールをいくつか作って使っている為、環境で挙動が変化するとしたら心配です。
実行したソースと結果を張り付けておきます。

ソース

using System;
using System.IO;

class MainApp
{
    public static void Main()
    {
        ShowDirectorys();
    }

    private static void ShowDirectorys()
    {
        string path1 = @"c:\tmp";
        Show(path1, Directory.GetFiles(path1, "*.xls")); // sample.xls, sample.xlsx どちらも取得できる

        string path2 = @"d:\tmp";
        Show(path2, Directory.GetFiles(path2, "*.xls")); // sample.xls のみ取得できる
    }

    private static void Show(string title, string[] texts)
    {
        Console.WriteLine( "===== " + title + " =====");
        foreach(var text in texts)
        {
            Console.WriteLine(text);
        }
        Console.WriteLine("==========");
    }
}


結果

===== c:\tmp =====
c:\tmp\sample.xls
c:\tmp\sample.xlsx
==========
===== d:\tmp =====
d:\tmp\sample.xls
d:\tmp\sample.xlsx
==========

以上、失礼しました。

投稿 2017/01/26 23:29

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/26 23:43

    検証ありがとうございます。
    私も Windows7(x64) を用意して試してみたところ、正常に動作しました。

    現状は、Windows10、及び WindowsServer2016 で問題の発生を確認しています。
    OS依存なのかもしれません。。

    キャンセル

  • 2017/01/27 18:58

    検証いただきありがとうございます。
    無事解決することができました。

    キャンセル

+1

Windows 10 Enterprise 64bit Version 1607 OS Build 14303.693
Cドライブ:NTFSの内蔵HDD
Dドライブ:FAT32のUSBメモリ
.NET Framework 4.6

で試しましたが、CもDも2つのファイルが取得されました。
Ragさんとほぼ同じソースで、出力結果も一緒です。

しかし。
Dを容量固定のVHDでNTFSフォーマットして試してみたところ、
Nakashigeさんと同様にDはsample.xlsしか取得されませんでした。

OSとドライブのフォーマット の組み合わせが影響するのかもしれません。
あとはシステムドライブかそうでないか、
リムーバブルかどうか、
など色々考えられますね。

投稿 2017/01/27 13:25

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.78%

関連した質問

同じタグがついた質問を見る

  • C#

    3869questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

閲覧数の多いC#の質問