2012年11月25日日曜日

( C# )フォルダ以下の特定の拡張子のファイルをすべて取得する

はいどうも。お久しぶりです。
ブログはこれからも細々と続けようかと思っています。更新頻度はがっつり減るとおもいますがね。

今回はC#フォルダ以下の特定の拡張子のファイルをすべて取得するコードを書いていきます。空クラス作って以下コピペで動くかと思います。

ではコードを


    class Search
    {
        /// <summary>
        /// フィルタ対象拡張子を格納
        /// </summary>
        static private string[] targetExtentions;

        /// <summary>ルートパス以下全てのファイルを指定拡張子のみでフィルタリングして取得する(非再帰)</summary>
        /// <param name="root_path" />検索対象絶対フォルダパス
        /// <param name="extention" />検索拡張子名配列(この配列に合致した拡張子のファイルを全て取得する)
        static public string[] FileSearchAllDirctory(string root_path, string[] extention)
        {
            if (extention == null) return null;

            targetExtentions = extention;
            List<string> pathList = new List<string>();
            Stack<string> dirctory_stack = new Stack<string>(200);
           
            Func<string bool="bool"> filter_function = new Func<string bool="bool">(Filtering);

            if (!Directory.Exists(root_path))
            {
                throw new ArgumentException();
            }

            dirctory_stack.Push(root_path);

            while (dirctory_stack.Count > 0)
            {
                string current_path = dirctory_stack.Pop();//検査対象パスを格納
                string[] sub_path = null;//current_path内の全てのフォルダパスを格納する配列

                try
                {
                    sub_path = Directory.GetDirectories(current_path);//current_path内の全てのフォルダを全て抽出する。
                }
                catch (UnauthorizedAccessException)
                {
                    continue;
                }
                catch (DirectoryNotFoundException)
                {
                    continue;
                }
                catch
                {
                    continue;
                }

                IEnumerable<string> raw_file_array = null;
                IEnumerable<string> filtering_file_array = null;

                try
                {
                    raw_file_array = Directory.GetFiles(current_path);
                    filtering_file_array = Enumerable.Where<string>(raw_file_array, filter_function);
                }
                catch (UnauthorizedAccessException)
                {
                    continue;
                }
                catch (DirectoryNotFoundException)
                {
                    continue;
                }
                catch
                {
                    continue;
                }

                foreach (string file in filtering_file_array)
                {
                    FileAttributes attribute = File.GetAttributes(file);

                    if ((attribute & FileAttributes.Hidden) != 0)
                    {
                        continue;
                    }

                    try
                    {
                        pathList.Add(file);
                    }
                    catch (FileNotFoundException)
                    {
                        continue;
                    }
                    catch
                    {
                        continue;
                    }
                }

                foreach (string path in sub_path)
                {
                    FileAttributes attribute = File.GetAttributes(path);

                    if ((attribute & FileAttributes.Hidden) != 0)
                    {
                        continue;
                    }

                    dirctory_stack.Push(path);
                }
            }

            return pathList.ToArray();
        }

        /// <summary>ファイルのフィルタリングに使用。</summary>
        /// <param name="name" />絶対ファイルパス
        /// <returns>trueならば拡張子にヒット、falseなら違う</returns>
        static private bool Filtering(string name)
        {
            string extention = string.Empty;

            try
            {
                extention = Path.GetExtension(name);

                foreach (string target_extention in targetExtentions)
                {
                    if (string.Compare(extention, target_extention, true) == 0)
                    {
                        return true;
                    }
                }
            }
            catch
            {
                return false;
            }

            return false;
        }
    }

まぁ説明せずとも見ればわかるはずです。 使い方は
string[] files = Search.FileSearchAllDirctory(@"C:\", new string[] { ".txt", ".jpg", ".bmp" });
のように使います。 以上です。

FileSearchAllDirctoryはマイクロソフトの非再帰取得関数の説明ページを参考にしました。