亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 在讀取文件但同時使用流時避免 java.lang.OutOfMemoryError

Java 在讀取文件但同時使用流時避免 java.lang.OutOfMemoryError

躍然一笑 2022-12-28 14:33:54
我正在嘗試讀取一個非常大的流文件,所以我需要并行流而不是每行迭代......我正在嘗試如下: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()進一步提高性能。


查看完整回答
反對 回復 2022-12-28
?
守著星空守著你

TA貢獻1799條經驗 獲得超8個贊

java 堆內存是有限的。我們不能同時讀取文件的全部數據。超過一定大小是不可能的(除非你增加堆內存,出于某些原因這并不理想)。我建議的是,分塊讀取文件,例如幾行,固定大小可能為 1000 行。然后運行拆分為數組并計算該塊的操作。

查看完整回答
反對 回復 2022-12-28
  • 2 回答
  • 0 關注
  • 129 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號