Java如何高效读取大型文件

后端 潘老师 7个月前 (10-20) 206 ℃ (0) 扫码查看

学习如何在Java中读取一个大小为GB级别的大型文件的所有行,并避免任何性能问题,例如内存使用过高或内存不足导致的OutOfMemoryError错误。

1.读取大型文件的策略

类似于XML文件的DOM解析器和SAX解析器,我们也可以使用两种方法来读取文件:

  • 在处理之前将整个文件读入内存
  • 逐行读取文件内容并独立处理每一行

第一种方法看起来更简洁,适用于内存需求非常低的较小文件(以千字节或少数几兆字节为单位)。如果用于读取大型文件,将很快导致数千兆字节文件的OutOfMemoryError错误。

第二种方法适用于读取数千兆字节的非常大的文件,当时将整个文件读入内存并不可行。在这种方法中,我们使用行流,即以流或迭代器的形式从文件中读取行。

本教程的重点是第二种方法的解决方案。

2. Java 8中的Files.lines() – 读取大型文件

使用Files.lines()方法,文件的 contents 被读取和处理,而且它是延迟计算的,所以在任何给定的时间,只有文件的一小部分存储在内存中。

这种方法的一个好处是我们可以直接编写Consumer操作,并使用Stream等较新的语言特性(如lambda表达式)。

Path filePath = Paths.get("C:/temp/file.txt")
//try-with-resources
try (Stream<String> lines = Files.lines( filePath ))
{
  lines.forEach(System.out::println);
}
catch (IOException e)
{
  e.printStackTrace();
}

3. IO的FileUtils.lineIterator()常见用法

lineIterator()使用一个Reader来迭代指定文件的行。使用try-with-resources语句在读取文件后自动关闭迭代器。

不要忘记将最新版本的的commons-io模块导入到项目的依赖中。

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>
File file = new File("C:/temp/file.txt");
try(LineIterator it = FileUtils.lineIterator(file, "UTF-8")) {
  while (it.hasNext()) {
    String line = it.nextLine();
    // do something with line
    System.out.println(line);
  }
} catch (IOException e) {
  e.printStackTrace();
}

4.阅读大型二进制文件

请注意,当我们通过流或逐行读取文件时,我们指的是字符型或文本文件。读取二进制文件时,UTF-8字符集可能会损坏数据,因此上述解决方案不适用于二进制数据文件。

要读取大型原始数据文件,例如电影或大型图像,我们可以使用Java NIO的ByteBuffer和FileChannel类。请记住,您需要尝试不同的缓冲区大小,并选择最适合您的缓冲区大小。

try (RandomAccessFile aFile = new RandomAccessFile("test.txt", "r");
  FileChannel inChannel = aFile.getChannel();) {
  //Buffer size is 1024
  ByteBuffer buffer = ByteBuffer.allocate(1024);
  while (inChannel.read(buffer) > 0) {
    buffer.flip();
    for (int i = 0; i < buffer.limit(); i++) {
      System.out.print((char) buffer.get());
    }
    buffer.clear(); // do something with the data and clear/compact it.
  }
} catch (IOException e) {
  e.printStackTrace();
}

5.结论

本Java教程讨论了应该使用哪些类来有效地读取大型文件。正确的解决方案取决于文件的类型和特定问题的其他决定因素。

我建议在您的环境中对所有解决方案进行基准测试,并根据它们的性能选择它们。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/10165.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】