0

現在、特定の基準に基づいてファイルを列挙するファイル スキャナーを作成しています。スキャン オプションの 1 つは、事前定義されたサイズより大きいファイルを除外することです。このルールは、個々のディレクトリとその子に適用できます。

たとえば、ユーザーは、C:\Users{USERNAME}\Documents から 1GB 未満のファイルのみを取得するルールを指定できます。したがって、ユーザーがドキュメント フォルダー内のディレクトリをスキャンすることにした場合、次のように言えます。C:\Users\{USERNAME}\Documents\SOMEDIR1\SOMEDIR2\指定されたルールがそのディレクトリに適用され、サイズが 1GB 以下のファイルのみが読み込まれます。

Dictionary<string, long> dSizeLimit;現在、キーが完全なディレクトリ パスであり、値がルールのファイル サイズ (バイト単位) であると定義されたディクショナリにルールを格納しています。

現在、次の方法を使用して、入力されたファイルのリストからファイルを除外する必要があるかどうかを判断しています。

public void SearchDirectory(DirectoryInfo dir_info, List<string> file_list, ref long size, ScanOptions Opt = null)
        {
            if (Opt == null)
                Opt = DefaultOption;
            try
            {
                foreach (DirectoryInfo subdir_info in dir_info.GetDirectories())
                {
                    SearchDirectory(subdir_info, file_list, ref size, Opt);
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Failed to enumerate directory: {0}", dir_info.FullName);
                Console.WriteLine("Exception: {0}", ex.Message);
            }

            try
            {

                foreach (FileInfo file_info in dir_info.GetFiles())
                {
                    //Here I iterate over all the size rules to determine if the current file should be added to the file_list 
                    foreach (KeyValuePair<string,long> entry in Opt.dSizeLimit)
                    {
                        if(string.Compare(entry.Key, 0, file_info.FullName, 0, entry.Key.Length, true)==0)
                        {
                            if (entry.Value > 0 && file_info.Length > entry.Value)
                                continue;
                        }
                    }

                    file_list.Add(file_info.FullName);
                    size += file_info.Length;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Failed to enumerate directory: {0}", dir_info.FullName);
                Console.WriteLine("Exception: {0}", ex.Message);
            }
        }

ScanOptions は、サイズ ルールを含むすべてのスキャン ルールを含む構造体です。コードからわかるように、現在、すべてのルールを繰り返し処理して、現在のファイルをファイル リストに含めるかどうかを決定しています。dSizeLimitユーザーは必要なルールを追加できるため、ディクショナリのエントリ数は制限されていないため、これは致命的となる可能性があります。

そのようなルックアップを処理するためのより良い方法はありますか?

PS ターゲット フレームワークは .NET 2.0 である必要があることに注意してください。そのため、LINQ やその他の 2.0 に適していない名前空間は問題外です。

4

1 に答える 1

1

ルールがディレクトリベースで適用される場合、ファイルを反復処理する前に、次のように最も制限の厳しいルールを決定できます。

long maxSize = long.MaxValue;
foreach (KeyValuePair<string,long> entry in Opt.dSizeLimit) {
    if(dir_info.FullName.StartsWith(entry.Key)) {
        maxSize = Math.Min(maxSize, entry.Value);
    }
}
// now iterate on the files, if no rules were present, file size
// should always be < long.MaxValue

同じフォルダにあるファイルについて毎回ルールを再スキャンする理由はありません(私が正しく理解していれば)。したがって、これにより多くの操作を節約できます。

辞書での反復を避けるために、オプションstructに1つの値だけを設定し、フォルダーを反復処理するときに、次のような適切な値でstructを構築できます(疑似コード、アイデアを提供するため)。

foreach (DirectoryInfo subdir_info in dir_info.GetDirectories()) {
    ScanOptions optForSubFolder = Opt;
    if (/* more specific rules for given subfolder */) {
        optForSubFolder.SizeLimit = /* value for subfolder */;
    }
    SearchDirectory(subdir_info, file_list, ref size, optForSubFolder);
}
于 2012-07-10T07:36:14.873 に答える