JDK8:用java.nio.file.Files.lines方法读取大型文件

ops/2024/10/18 18:13:22/

先说结论:

如果要读取一个大文件(文件大小超过了内存大小),则可以考虑使用java.nio.file.Files.lines方法来读取这个大型文件的内容。

关于java.nio.file.Files类中lines方法的说明:

 jdk1.8.0_311中原码部分:

java">    /*** Read all lines from a file as a {@code Stream}. Unlike {@link* #readAllLines(Path, Charset) readAllLines}, this method does not read* all lines into a {@code List}, but instead populates lazily as the stream* is consumed.** <p> Bytes from the file are decoded into characters using the specified* charset and the same line terminators as specified by {@code* readAllLines} are supported.** <p> After this method returns, then any subsequent I/O exception that* occurs while reading from the file or when a malformed or unmappable byte* sequence is read, is wrapped in an {@link UncheckedIOException} that will* be thrown from the* {@link java.util.stream.Stream} method that caused the read to take* place. In case an {@code IOException} is thrown when closing the file,* it is also wrapped as an {@code UncheckedIOException}.** <p> The returned stream encapsulates a {@link Reader}.  If timely* disposal of file system resources is required, the try-with-resources* construct should be used to ensure that the stream's* {@link Stream#close close} method is invoked after the stream operations* are completed.*** @param   path*          the path to the file* @param   cs*          the charset to use for decoding** @return  the lines from the file as a {@code Stream}** @throws  IOException*          if an I/O error occurs opening the file* @throws  SecurityException*          In the case of the default provider, and a security manager is*          installed, the {@link SecurityManager#checkRead(String) checkRead}*          method is invoked to check read access to the file.** @see     #readAllLines(Path, Charset)* @see     #newBufferedReader(Path, Charset)* @see     java.io.BufferedReader#lines()* @since   1.8*/public static Stream<String> lines(Path path, Charset cs) throws IOException {BufferedReader br = Files.newBufferedReader(path, cs);try {return br.lines().onClose(asUncheckedRunnable(br));} catch (Error|RuntimeException e) {try {br.close();} catch (IOException ex) {try {e.addSuppressed(ex);} catch (Throwable ignore) {}}throw e;}}/*** Read all lines from a file as a {@code Stream}. Bytes from the file are* decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8}* {@link Charset charset}.** <p> This method works as if invoking it were equivalent to evaluating the* expression:* <pre>{@code* Files.lines(path, StandardCharsets.UTF_8)* }</pre>** @param   path*          the path to the file** @return  the lines from the file as a {@code Stream}** @throws  IOException*          if an I/O error occurs opening the file* @throws  SecurityException*          In the case of the default provider, and a security manager is*          installed, the {@link SecurityManager#checkRead(String) checkRead}*          method is invoked to check read access to the file.** @since 1.8*/public static Stream<String> lines(Path path) throws IOException {return lines(path, StandardCharsets.UTF_8);}

 从javadoc注解中可以看出,它将文件中的所有行作为 Stream 读取,与 readAllLines 不同,此方法不会将所有行读入 List 中(不全部加载到内存中),而是在流被使用时延迟填充(populates lazily)

java.nio.file.Files 类中的 lines 方法是 Java 8 引入的一个非常有用的方法,用于处理文件和目录的 I/O 操作,它提供了一种流式(Stream-based)的方式来读取文件内容,并将文件的每一行作为字符串(String)对象进行处理。

lines(Path path)方法使用默认字符集(通常是 UTF-8)来解码文件中的字节。

使用场景:

  1. 文本文件处理:当你需要读取和处理大量文本文件时,lines 方法可以方便地按行处理文件内容。
  2. 数据分析和转换:如果你需要对文件中的数据进行分析或转换,可以将 lines 方法返回的 Stream 对象与其他 Stream 操作(如 mapfilterreduce 等)结合使用。
  3. 日志处理:对于日志文件的分析和监控,lines 方法可以方便地读取日志文件并按行进行处理。
  4. 批量文本操作:对于需要批量处理文本文件的场景(如批量重命名、查找和替换等),lines 方法可以提供一个高效且简洁的解决方案。

优缺点:

优点

  1. 简洁性:与传统的文件读取方式相比,lines 方法更加简洁和直观。
  2. 流式处理:与 Stream API 紧密集成,使得文件处理更加灵活和高效。
  3. 内存效率默认情况下,lines 方法使用懒加载(lazy loading)方式读取文件内容,这意味着它不会一次性加载整个文件到内存中,从而减少了内存使用。

缺点

  1. 字符集问题lines 方法默认使用系统默认字符集来解码文件内容。如果文件使用了非默认字符集(如 ISO-8859-1),则需要手动指定字符集,否则可能会出现乱码问题。
  2. 错误处理:与 BufferedReader 或 Scanner 相比,lines 方法在处理文件读取错误时可能不太直观。你需要使用 try-catch 块来捕获和处理可能发生的 IOException
  3. 性能考虑:虽然 lines 方法在大多数情况下都足够高效,但在处理大文件时,由于它使用 Stream API,可能会增加一些额外的开销。此外,如果你需要多次读取同一文件或进行大量的小文件读取操作,使用传统的文件读取方式可能会更加高效。

示例代码:

java">import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;public class FilesTest {public static void main(String[] args) {String filePath = "page\example.txt";// 使用默认字符编码读取文件的每一行try (Stream<String> lines = Files.lines(Paths.get(filePath))) {lines.forEach(System.out::println);} catch (IOException e) {e.printStackTrace();}// 使用指定的字符编码读取文件的每一行try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {lines.forEach(System.out::println);} catch (Exception e) {e.printStackTrace();}}}

所以,如果之后遇到需要读取大型文件的内容进行处理又担心内存不足问题时,可以考虑使用Files.lines方法来进行处理哦~~~,它是在jdk1.8中引入的


http://www.ppmy.cn/ops/45029.html

相关文章

云计算-使用Java访问S3 (Accessing S3 using Java)

为了访问桶&#xff0c;我们使用AWS Java API。我们将使用API的2.0版本&#xff0c;但在撰写本文时&#xff0c;这是一个非常新的版本&#xff0c;因此您在互联网上找不到许多代码示例。版本1与版本2不兼容&#xff0c;不同的子版本之间也不兼容&#xff0c;因此我们必须非常小…

HaloDB 的 Oracle 兼容模式

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ 前倾回顾 前面介绍了“光环”数据库的基本情况和安装办法。 哈喽&#xff0c;国产数据库&#xff01;Halo DB! 三步走&#xff0c;Halo DB 安装指引 ★ HaloDB是基于原生PG打造的新一代高性能安…

在 C++ 中,p->name 和 p.name 的效果并不相同。它们用于不同的情况,取决于你是否通过指针访问结构体成员。

p->name&#xff1a;这是指针访问运算符&#xff08;箭头运算符&#xff09;。当 p 是一个指向结构体的指针时&#xff0c;用 p->name 来访问结构体的成员。 student* p &stu; // p 是一个指向 student 类型的指针 cout << p->name << endl; // 通过…

20240529瑞芯微官方Toybrick TB-RK3588开发板的Debian11下使用SCP拷贝文件

20240529瑞芯微官方Toybrick TB-RK3588开发板的Debian11下使用SCP拷贝文件 2024/5/29 20:48 1、ADB链接异常。 2、BT打开之后找不到设备&#xff1f; 不清楚&#xff1a;是我拿到的开发板的问题&#xff0c;还是Toybrick/Rockchip官方没有做好。 3、现在最新版本的WINSCP&…

PyTorch自定义张量操作开发指南【CFFI+CUDA】

PyTorch 与 TensorFlow 一起成为深度学习研究人员和从业者的标准。虽然 PyTorch 在张量运算或深度学习层方面提供了多种选择&#xff0c;但一些专门的操作仍然需要手动实现。在运行时至关重要的情况下&#xff0c;应使用 C 或 CUDA 来完成此操作&#xff0c;以支持 CPU 和 GPU …

职校老师的工资待遇怎么样

工资水平一直是教师们关注的焦点&#xff0c;毕竟&#xff0c;工资不仅关系到个人的生活品质&#xff0c;还影响着教师的职业满意度和工作动力。职校教师的工资待遇究竟是怎样的呢&#xff1f; 职校教师的工资水平受多种因素影响&#xff0c;包括地区、学校类型、个人资历和教学…

MySQL库操作

目录 一、基本的库操作 二、库的备份与恢复 MySQL登录选项 -h&#xff1a;指明登录部署了mysql服务的的主机 -P&#xff1a;指明访问的端口号 -u&#xff1a;指明登录的用户 -p&#xff1a;指明登陆密码 mysql -h xxx.x.x.x -P xxxx -u xxx -p xxxxxxxxx 一、基本的库…

力扣:541. 反转字符串 II

541. 反转字符串 II 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xff0c;就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个&#xff0c;则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个&#xff0…