为了账号安全,请及时绑定邮箱和手机立即绑定

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 关注
  • 148 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号