2015-11-06 13 views
5

私は100,000個のファイルを持つディレクトリを持っており、値を読むためにそれらをすべて反復する必要があります。今はlistFiles()を使用して配列内のすべてのファイルをロードし、次に1つずつ繰り返します。しかし、配列をロードせずにこれを行うメモリ効率的な方法はありますか?ディレクトリ内の大規模なファイルを反復する

File[] tFiles = new File(Dir).listFiles(); 

try { 
    for (final File tFile : tFiles) { 
     //Process files one by one 
    } 
} 
+0

[私は以前に与えた答え役立つかもしれない](http://stackoverflow.com/questions/27898652/how-to-read-multiple-text-files-in-java-for-gui-use-didnt-find-the-answer/27900034#27900034) 一部の機能を変更する必要がありますが、ストリームを使用する方が効率的です。しかし、パフォーマンスについてはわかりません。 – easyDaMan

答えて

6

Java 7以降では、ファイルビジターパターンを使用してディレクトリの内容を再帰的に参照できます。

FileVisitorインターフェイスのマニュアルはhereです。

これにより、Fileオブジェクトの大きな配列を作成せずにファイルを反復処理できます。

Path start = Paths.get(new URI("file:///my/folder/")); 

Files.walkFileTree(start, new SimpleFileVisitor<Path>() { 
    @Override 
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
     throws IOException 
    { 
     System.out.println(file); 
     return FileVisitResult.CONTINUE; 
    } 
    @Override 
    public FileVisitResult postVisitDirectory(Path dir, IOException e) 
     throws IOException 
    { 
     if (e == null) { 
      System.out.println(dir); 
      return FileVisitResult.CONTINUE; 
     } 
     else { 
      // directory iteration failed 
      throw e; 
     } 
    } 
}); 
+0

ありがとう!これはまさに私が探していたものでした:) – prem89

+0

@ prem89よろしくお願いします! – Mena

1

あなたはJDKのFileVisitorに付属している過度の決まり文句を避けたい場合は、あなたがGuavaを使用することができます:あなたのファイル名をプリントアウトする

簡単な例。 Files.fileTreeTraverser()はあなたがフォルダ(あるいはサブフォルダ)にファイルを移動するために使用することができますTreeTraverser<File>を与える:

for (File f : Files.fileTreeTraverser() 
        .preOrderTraversal(new File("/parent/folder"))) { 
    // do something with each file 
} 
+0

これは内部的に 'Collections.unmodifiableList(Arrays.asList(files));'を呼び出します。つまり、これは質問自体のコードとしては良くないと思います。 – jan

+0

@janは、あなたが「より良い」という意味にかかっています。私はGuavaの 'TreeTraverser'が好きです。なぜなら、これは非常に強力な抽象であり、あなたのことを簡潔かつ読みやすくすることができ、バグの余地が少なくなるからです。はい、それは最もパフォーマンスの高いソリューションではないかもしれませんが、ほとんどの場合、これはおそらくアプリケーションのボトルネックではありません。これは100kファイルのOPの場合でも当てはまるかもしれません。私はまず、可能な限り単純なソリューションを使用し、可能な限り単純なソリューションでは十分でない場合にのみ、パフォーマンスを最適化します。 –

+0

他の状況では私は全く同意しますが、効率的な解決策に関するこの質問の答え/コメントとして私は同意できません。さらに100kのファイルがあるかもしれません。 – jan

2

のJava 8遅延ロードストリームバージョン:

Files.list(new File("path to directory").toPath()).forEach(path -> { 
    File file = path.toFile(); 
    //process your file 
}); 
関連する問題