2015-11-08 16 views
6

Klasördeki tüm dosyalar üzerinde salt okunur bir işlem yapmam gerekiyor. Dosya akışı almak için Files.walk kullanıyorum, ancak api'nin, walk'un yalnızca bir paralel akışı değil, yalnızca normal bir akışı döndürdüğünü belirlediğini fark ettim.Paralel bir File.walk akışı nasıl edinebilirim?

Dizindeki tüm dosyaları paralel olarak nasıl işlerim?

+4

Belki de Files.walk (...). Parallel() 'gibi bir şey? – Flown

+0

@Flown Hah ... aptalca bana. Normal akışları paralel olarak dönüştürebileceğinizi farketmediniz. –

cevap

15

Stream::parallel'u çağırarak, Stream'u herhangi bir paralel Stream dönüştürebilirsiniz.

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

'Files.walk', özellikle alt ağacınızın 1024'ten küçük dosyalara sahip olması durumunda zayıf bir şekilde paralel olduğuna dikkat edin. Dosya başına çok işlemeniz varsa ve çok fazla dosya yoksa, Files.walk (yol) .collect (toList()). ParallelStream() 'için daha verimli olacaktır. –

+1

@TagirValeev İlginç. Bunun neden böyle olduğunu açıklayan bir bağlantınız var mı? –

+7

@DavidGrinberg, JDK kaynak kodu ve kriterleri. Spliterators.spliteratorUnknownSize işlevini dahili olarak kullanarak, bölme stratejisi, 1024 öğeyle başlayan dizileri yığınlar halinde yüklemektir. Boyut bilinmediği için, Stream boru hattı motoru, parçanın eşit bölümleri oluşturduğunu varsayar, ancak aslında değildir (ilk önce <= 1024 girdi tüm öğeleri, sonek için hiçbir öğe bırakmadan önek içine döker). Bu, çok kötü bir paralel performansla sonuçlanır. –