我正在尝试读取一个非常大的流文件,所以我需要并行流而不是每行迭代......我正在尝试如下: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
提交
取消
