2017-04-05 15 views
0

再帰を使用して特定の種類のファイルを検索しました(たとえば、.pdfファイルがここで使用されています)。 再帰アルゴリズムはすべてのサブフォルダを検索します。 しかし、サブフォルダが多すぎるとパフォーマンスが低下することがわかりました。サブ・サブフォルダ、サブ・サブ・サブフォルダ。 ファイル検索に適したアルゴリズムがあるかどうかを知りたい。再帰よりも優れたファイル検索アルゴリズムはありますか?

以下はファイル検索用の再帰コードです。私は、例

import java.io.File; 
public class FInd { 
    public static void main(String[] args) { 
     File f = new File("D:/"); 
     find(f);  
    } 
    public static void find(File f){  
     File []list = f.listFiles(); 
     try{ 
      for(int i=0;i<list.length && list.length>0;i++){  
       if(list[i].isFile() && (list[i].getName().contains(".pdf")) || 
         list[i].getName().contains(".PDF")) 
        System.out.println(list[i].getAbsolutePath()); 
       if(list[i].isDirectory()) find(list[i]); 
      } 
     }catch(Exception e){  
     } 
    } 
} 

このコードは、ファイルエクスプローラでオプションを検索するために比較したときに多少速いかまたは等しいように.pdfファイルを使用しています。私はあなたがマルチスレッドを使用することができ、この

+3

*再帰*はアルゴリズムではなく、実装*の選択です。あなたには検索スペースがあり、ファイルを見つけるためにそれを探索する必要があります。だから、フォルダ間の名前と賢い関係がない限り、全体の空間を探索する必要があります。 – Arash

+1

http://stackoverflow.com/questions/4852531/find-files-in-a-folder-using-java – prasanth

+0

jdk7以上を使用している場合はFiles.walkFileTreeを使用してください。https://docs.oracle.com/javase/チュートリアル/ essential/io/find.html –

答えて

1

反復的な方法

public class Find { 
public static void main(String[] args) { 

    File f = new File("D:/"); 

    Stack stack = new Stack<File>(); 

    stack.push(f); 

    while (!stack.empty()) 
    {  
     f = (File) stack.pop(); 
     File []list = f.listFiles(); 
     try{ 
      for(int i=0;i<list.length && list.length>0;i++){  
       if(list[i].isFile() && (list[i].getName().contains(".pdf")) || 
         list[i].getName().contains(".PDF")) 
        System.out.println(list[i].getAbsolutePath()); 
       if(list[i].isDirectory()) stack.push(list[i]); 
      } 
     }catch(Exception e){  
    } 
} 
を試してみてください
+0

ありがとう。これは役に立ちました。ちょっとした修正:** f = stack.pop(); File [] list = f2.listFiles(); ** は に置き換えてください。f =(File)stack.pop(); File [] list = f.listFiles(); –

+0

それは役に立ちましたことをうれしく思っています。私は答えを編集します(私は 'f'の代わりに' f2'を置く理由はありません:p)。 – Abdou

1

Probaplyよりも速くアルゴリズムを知りたい...

あなたが入力した各フォルダには、あなたがあなたのCPUよりも多くのスレッドを持っていても...新しいスレッドで開始し、それWindowsのはるかに多くのスレッドを実行することができるので問題ではありません...

+3

パフォーマンスを向上させる可能性は低いです。パフォーマンスのボトルネックはディスクから読み取っているため、パフォーマンスを低下させる可能性はさらに高くなります。同時にディスク上の2か所から読み取ろうとすると、パフォーマンスが低下します。 *(免責条項:非SSDディスクと仮定)* – Andreas

+0

また、スレッド数を制限してください。何千ものスレッドを作成すると、OS全体がハングアップする可能性があります。 –

+0

@JaroslawPawlakあなたは正しいですが、フォルダが終了した後にスレッドが停止することを覚えておいてください。)...ほとんどの場合、フォルダはあまりにも長くない(ファイルの内容)スレッドが本当に速く閉じている理由... – mirisbowring

2

スレッドを使用すると、起動時にコストがかかるため、ファイル参照+再帰の増加がN個のフォルダ/スレッド。

これは、ループ(再帰のための古典的な交換)

static boolean avoidRecursion(String target){ 
    File currentDir = new File(System.getProperty("user.home")); 
    Stack<File> dirs = new Stack<File>(); 
    dirs.push(currentDir); 

    do{ 
     for(File f : dirs.pop().listFiles()){ 
      if (f.isDirectory()) 
       dirs.push(f); 
      else{ 
       if (f.getName().equals(target)) 
        return true; 
      } 
     } 
    }while(!dirs.isEmpty()); 
    return false; 
} 

測定の両方のアプローチを使用しているオプションを選択し、簡単な方法であり、より速く

+0

これは興味深いようです。私はそれを試してみます –

1

Java8ストリームを返すFiles.walk()メソッドを使用します。パラレルストリームを使用すると、その計算を非常に簡単に並列化できます。

は資源方法で試しに以下の便利なイディオムを使用します。

試し(ストリームヴァルス= Files.walk(ROOTPATH)){....}

ROOTPATHでは、あなたが使用することができますPaths.get( "root location")実際にルートの場所に移動します。

関連する問題