2015-11-08 3 views
6

フォルダ内のすべてのファイルに対して読み取り専用の処理を再帰的に行う必要があります。私はFiles.walkを使ってファイルのストリームを取得していますが、APIのwalkは、パラレルストリームではなく通常のストリームのみを返すよう指定しています。Files.walkの並列ストリームを取得するにはどうすればよいですか?

ディレクトリ内のすべてのファイルを並行して処理する方法を教えてください。

+4

「Files.walk(...)。parallel()」のようなものでしょうか? – Flown

+0

@Flown Hah ...愚かな私。通常のストリームをパラレルに変換できることは分かりませんでした。 –

答えて

15

Streamは、Stream::parallelを呼び出して、Streamのパラレルに変換できます。

Stream<Path> stream = Files.walk(startPath).parallel().forEach(...); 
+9

特に、サブツリーのファイルが1024未満である場合、 'Files.walk'は並列化が悪いことに注意してください。ファイルごとの処理が多く、それほど多くのファイルがない場合は、おそらく 'Files.walk(path).collect(toList())。parallelStream()'の方が効率的です。 –

+1

@TagirValeev興味深い。これがなぜそうであるかを説明するリンクがありますか? –

+7

@DavidGrinberg、JDKのソースコードとベンチマーク'Spliterators.spliteratorUnknownSize'を内部的に使用します。これは、1024要素から始まる配列にチャンクをロードすることです。サイズが不明なので、ストリームパイプラインエンジンは、splitは偶数の部分を生成すると仮定しますが、実際にはそうではありません(先頭の<1024の入力は、すべての要素を接頭辞にダンプします。これは非常に悪い並列パフォーマンスをもたらします。 –