我正在嘗試讀取一個非常大的流文件,所以我需要并行流而不是每行迭代......我正在嘗試如下:String cont = new String(Files.readAllBytes(Paths.get(this.File_Path)), StandardCharsets.UTF_8); List<String> words = Arrays.asList(cont.split("\\PL+"));yep = words.parallelStream() .filter(x -> x.contains(toMatch)) .distinct() .collect(Collectors.toList());這適用于小文件大小,但如果我嘗試對具有一些 gbs 大小的文件進行相同操作,java 會給我這個異常:java.lang.OutOfMemoryError: Required array size too large有一種方法可以避免此異常但同時使用并行流而不是使用 BufferReader 或 Scanner 進行迭代?
2 回答

婷婷同學_
TA貢獻1844條經驗 獲得超8個贊
問題是Files.readAllBytes()
。它將文件的全部內容加載到 a 中String
,因此在內存中。
要逐行讀取,您要使用Files.lines()
它返回 aStream<String>
然后將其轉換為并行流并對它進行轉換操作:
List<String> words = Files.lines(Paths.get(this.File_Path), charSetOfYourFileIfNotUTF8) // Stream<String> .parallel() .flatMap(s-> Arrays.stream(s.split("\\PL+"))) // Stream<String> .filter(x -> x.contains(toMatch)) .distinct() .collect(Collectors.toList());
關于性能,請注意distinct()
在并行管道中使用維護順序的收集是昂貴的。
您應該考慮toSet()
進一步提高性能。

守著星空守著你
TA貢獻1799條經驗 獲得超8個贊
java 堆內存是有限的。我們不能同時讀取文件的全部數據。超過一定大小是不可能的(除非你增加堆內存,出于某些原因這并不理想)。我建議的是,分塊讀取文件,例如幾行,固定大小可能為 1000 行。然后運行拆分為數組并計算該塊的操作。
添加回答
舉報
0/150
提交
取消