4

すべての音楽ファイルにインデックスを付けてデータベースに保存したいと思います。私には、音楽ドライブのルートから始めて、再帰的に呼び出すこの関数があります。

すなわち

start > ReadFiles(C:\music\);

ReadFiles(path){
   foreach(file)
      save to index;

   foreach(directory)
      ReadFiles(directory);
}

これは正常に機能しますが、プログラムの実行中に使用されるメモリの量が増え、最終的にシステムのメモリが不足します。

このタスクを完了するために4GBのRAMを必要としないより良いアプローチを持っている人はいますか?

よろしく、Tys

4

5 に答える 5

10

Alxandrのキューベースのソリューションは正常に機能するはずです。

.NET 4.0を使用している場合は、Directory.EnumerateFilesファイルをすべてメモリにロードせずに、ファイルを遅延して列挙する新しい方法を利用することもできます。

void ReadFiles(string path)
{
    IEnumerable<string> files =
        Directory.EnumerateFiles(
            path,
            "*",
            SearchOption.AllDirectories); // search recursively

    foreach(string file in files)
        SaveToIndex(file);
}
于 2010-11-21T21:16:48.517 に答える
2

ルートを除くすべてのディレクトリに表示されるエントリ.とエントリを確認しましたか?..

それらをスキップしないと、無限ループになります。

于 2010-11-21T21:15:24.393 に答える
1

これをキューとして実装できます。これでメモリを節約できると思います(ただし、よくわかりません)。少なくともそれはあなたのスタックを解放するでしょう。フォルダを見つけたらキューに追加し、ファイルを見つけたらそれを読みます。これにより、再帰が防止されます。

このようなもの:

Queue<string> dirs = new Queue<string>();
dirs.Enqueue("basedir");
while(dirs.Count > 0) {
    foreach(directory)
        dirs.Enqueue(directory);
    ReadFiles();
}
于 2010-11-21T21:10:45.917 に答える
0

ただし、ファイルにアクセスできない場合、パスが長すぎる場合、またはその他の例外が発生した場合は、EnumerateFiles()の実行が停止することに注意してください。これは私がそれらの問題を解決するために今のところ使用しているものです:

public static List<string> getFiles(string path, List<string> files)
{
    IEnumerable<string> fileInfo = null;
    IEnumerable<string> folderInfo = null;
    try
    {
        fileInfo = Directory.EnumerateFiles(str);
    }
    catch
    {

    }
    if (fileInfo != null)
    {
        files.AddRange(fileInfo);
        //recurse through the subfolders
        fileInfo = Directory.EnumerateDirectories(str);
        foreach (string s in folderInfo)
        {
            try
            {
                getFiles(s, files);
            }
            catch
            {

            }
        }
    }
    return files;
}

使用例:

List<string> files = new List<string>();
files = folder.getFiles(path, files);

私のソリューションは、次のページのコードに基づいています:http: //msdn.microsoft.com/en-us/library/vstudio/bb513869.aspx

更新:ファイルを再帰的に取得するためのはるかに高速な方法は、http ://social.msdn.microsoft.com/Forums/vstudio/en-US/ae61e5a6-97f9-4eaa-9f1a-856541c6dcce/directorygetfiles-gives-me-にあります。 access-denied?forum=csharpgeneral。Stackを使用するのは初めてですが(存在することすら知りませんでした)、この方法は機能しているようです。少なくとも、CおよびDパーティション上のすべてのファイルがエラーなしで一覧表示されました。

于 2013-11-24T09:11:45.913 に答える
0

再帰を行うときに無限ループにつながるジャンクションフォルダである可能性がありますが、よくわかりません。これを確認して、自分で確認してください。リンク:https ://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mklink

于 2018-03-21T09:57:08.283 に答える