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

【故障排查:JDK8中Files.lines方法错误使用导致的Linux服务器文件描述符泄漏问题】 摘要: 文章分析了JDK8中Files.lines()方法错误使用导致的Linux服务器文件描述符泄漏问题。 阅读详情

先说结论:

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

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

 jdk1.8.0_311中原码部分:

    /**
     * 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 操作(如 map、filter、reduce 等)结合使用。
  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,可能会增加一些额外的开销。此外,如果你需要多次读取同一文件或进行大量的小文件读取操作,使用传统的文件读取方式可能会更加高效。

示例代码:

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中引入的

Java Files类:NIO.2文件操作的核心原理与工程实践 Files类是Java 7引入的NIO.2标准文件操作抽象,它取代了老旧的File类,提供声明式、线程安全、异常精细化的路径操作能力。其底层基于Path语义化抽象与FileSystemProvider插件机制,支持本地磁盘、ZIP、HDFS乃至云存储等多文件系统统一编程。技术价值在于将‘如何操作文件’升维为‘我要做什么’,显著提升代码可读性、可测性与跨平台鲁棒性。典型应用场景包括日志轮转、ETL数据处理、容器化部署脚本及微服务缓存一致性校验。本文深入解析Files类的设计哲学、核心API陷阱及生产级避坑方案 阅读详情

相关推荐

Java读取文件转字符串的7种写法与生产避坑指南

在Java中,将文件读取为字符串看似基础,实则涉及字符集编码、内存管理、平台兼容性与安全防护等多重技术维度。其核心原理是字节流到字符流的解码过程,依赖正确的Charset(如StandardCharsets.UTF_8)和缓冲策略;技术价值在于避免乱码、OOM和路径遍历等线上故障;典型应用场景包括配置加载、日志解析、微服务外部化配置等。尤其在JDK 11+环境下,Files.readString()凭借BOM自动识别与零拷贝优化成为首选,而JDK 8项目仍需谨慎使用Files.readAllBytes()配

weixin_34008784的博客 409

Files.lines()使用问题

Java8的标准库中增加了一个新的方法: 1 2 3 4 public final class Files { public static Stream<String> lines(Path path) throws IOException } 方法描述文档。 这个方...

以爱护甲,爱满枫林。 9158

Python爬虫实战:逆向解析央视频加密参数(附完整代码)

本文详细解析了央视频加密体系的技术实现,通过Python逆向工程实战演示如何解密动态密钥、AES加密和自定义哈希算法等核心组件。文章提供完整代码示例,涵盖GUID生成、参数构造和异步请求处理,帮助开发者掌握现代视频平台的反爬机制破解方法。

weixin_42532473的博客 1129

如何读取大文件?(java) 流式读取Files.lines()

如何读取大文件?(java) 流式读取 当文件过大,并且你设置的 内存过下或者无法满足文件内存,一次性读取就会出现OOM内存溢出。 当这时可以使用 Files.lines() 方法解决 与 readAllLines 方法返回 List 不同,lines 方法返回的是 Stream。 这,使得我们在需要时可以不断读取、使用文件中的内容,而不是一次性地把所有内容都读 取到内存中,因此避免了 OOM。 LongAdder longAdder = new LongAdder();

jj89929665的博客 3621

Unity UGUI深度优化

Unity UGUI优化相关

不定时分享所学所得,包括游戏开发和其他收获! 2717

最新Docker GPU支持全解析:为什么nvidia-smi能用但PyTorch找不到CUDA?

本文深入解析了Docker容器中nvidia-smi命令可用但PyTorch无法调用CUDA的根本原因。关键在于默认配置仅暴露了GPU的utility管理能力,而CUDA计算所需的compute能力未被激活。通过正确设置NVIDIA_DRIVER_CAPABILITIES环境变量为compute,utility,并配合--gpus参数,即可解决此问题,确保AI训练等任务顺利进行。

convnet3designer的博客 237

Files.lines()方法使用相关问题

Files.lines方法使用的相关问题Files.lines()问题一原因解决总结 Files.lines() 以Stream流的形式读取文件的所有行 /** * 以流的形式读取文件的所有行 * 读取的的字节是以UTF-8解码的字符集 * * @param path 文件的路径 * @return Stream<String> 文件中的行组成的流 * @throws IOException 出现IO错误时抛出该异常 * @throws SecurityException 如

攻城狮Chova的博客 5025

【TiktokAPI】Tiktok直播API与实时互动功能开发完全指南

Tiktok直播API允许开发者创建、管理直播,并实现各种互动功能。/*** 获取Tiktok直播API访问令牌* @param {string} client_id - 应用ID* @param {string} client_secret - 应用密钥* @param {string} code - 授权码* @param {string} redirect_uri - 重定向URI* @returns {Promise<object>} 访问令牌响应*/try {}),

Mageia的专栏 3187

30G 上亿数据的超大文件,如何快速导入生产环境?

Hello,大家好,我是楼下小黑哥~ 如果给你一个包含一亿行数据的超大文件,让你在一周之内将数据转化导入生产数据库,你会如何操作? 上面的问题其实是小黑哥前段时间接到一个真实的业务需求,将一个老系统历史数据通过线下文件的方式迁移到新的生产系统。 由于老板们已经敲定了新系统上线时间,所以只留给小黑哥一周的时间将历史数据导入生产系统。 由于时间紧,而数据量又超大,所以小黑哥设计的过程想到一下解决办法: 拆分文件 多线程导入 欢迎关注我的公众号:小黑十一点半,获得日常干货推送。如果您对我的专题内容感兴趣,也

楼下小黑哥 663

8.2-12.4GHz喇叭天线设计

使用后处理模板的优化算法,对a1、h_horn、b1进行优化,各参数的优化区间即为之前计算得到的参数范围。由于矩形喇叭的辐射特型基本上是E面和H面扇形喇叭的结合,当波导中只是单模传播(只有TE波)时,矩形喇叭的口径可以通过远场公式推理出来。表示矩形喇叭的口径效率,进行最佳增益设计时,一般取值为0.5。从表中可以看出,该结构在8.58GHz的增益误差为2.68%>2.5%,需要对结构进行优化。建模完成,之后就是在矩形波导尾部添加波导端口激励,以及对应频率的远场监视器。,在这里,将频率定为区间的中心频率。

qq_48897427的博客 6655

在不同版本Python中安装PyQT5及PyQT5-Tools

在不同版本Python中安装PyQT5及PyQT5-Tools

zoomgu680的博客 2万+

java.nio.file.Files lines方法使用不当引发的文件句柄泄露

1. 问题描述 4月29日上午,测试同学通过压测工具测试"网关->业务层->分析服务"链路,QPS 200。 测试开始不久后,CloudMonitor告警"分析服务"服务器磁盘占用超过80%,经过排查,确定告警根原因是java.nio.file.Files lines方法使用不当引发的文件句柄泄露,临时文件被删除后磁盘空间未释放导致。 2. 排查步骤 测试开始后10分钟左右,Clo...

860MHz的专栏 1464

Codex 100个真实案例 - 用AI生成建筑平面图SVG(室内设计师的新武器)

本案例用 Codex 生成一套完整的 Python 脚本,自动绘制 SVG 格式的建筑平面图。我们会设计一个90平两室一厅的户型——客厅、主卧、次卧、厨房、卫生间一应俱全,还会自动摆放家具(沙发、床、餐桌、橱柜)、标注尺寸和面积、绘制水电路走向、生成多种配色方案。最终输出的 SVG 文件可以直接用浏览器打开展示,也可以转成 PNG 交给客户。室内设计师看了都说好!

yueyeguzhuo的专栏 757

java8读取文件代码_Jdk8一行代码读取文件

JDK7中引入了新的文件操作类java.nio.file.File,它包含了很多有用的方法来操作文件,比如检查文件是否为隐藏文件,或者是检查文件是否为只读文件。开发者还可以使用Files.readAllBytes(Path)方法把整个文件读入内存,此方法返回一个字节数组,还可以把结果传递给String的构造器,以便创建字符串输出。此方法确保了当读入文件的所有字节内容时,文件属性是关闭的,否则就会出...

weixin_39670246的博客 1019

基于深度学习的活体人脸检测系统:YOLOv5、YOLOv6、YOLOv7、YOLOv8实现与UI界面设计

本博客详细介绍了如何基于YOLOv5、YOLOv6、YOLOv7、YOLOv8模型实现一个完整的活体人脸检测系统。系统包括数据集准备、模型训练、UI界面设计以及实时检测功能的实现。通过YOLO系列模型的应用,我们能够高效、准确地进行人脸检测和活体验证。未来,随着YOLOv9和其他新一代目标检测模型的出现,我们可以进一步提高检测精度和速度。此外,集成更多的传感器数据(如深度传感器、红外线传感器)可以使活体检测系统更加安全和稳定。

YOLO 540

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

java 取文件更新使劲,java读取文件(更新jdk7及jdk8)

以字节的方式读取:InputStream inputStream = newFileInputStream(file);int temp = -1;StringBuilder sb= newStringBuilder();while((temp = inputStream.read()) != -1){sb.append((char)temp);}inputStream.close();也可以多个...

weixin_28723171的博客 189

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java7 files 读文件_JDK1.7 之java.nio.file.Files 读取文件仅需一行代码实现

JDK1.7中引入了新的文件操作类java.nio.file这个包,其中有个Files类它包含了很多有用的方法来操作文件,比如检查文件是否为隐藏文件,或者是检查文件是否为只读文件。开发者还可以使用Files.readAllBytes(Path)方法把整个文件读入内存,此方法返回一个字节数组,还可以把结果传递给String的构造器,以便创建字符串输出。此方法确保了当读入文件的所有字节内容时,无论是否...

weixin_39622332的博客 166

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

玩Java 8 – Lambda,路径和文件

我最近需要读取一堆文件,而不是仅仅抓住我和可能是大多数开发人员拥有的旧FileUtils.java,然后从一个项目复制到另一个项目,我决定快速看看其他方法。 是的,我知道有Commons IO和Google IO ,我为什么还要打扰? 他们可能会做得更好,但是我想检查一下NIO jdk类并同时使用lambda。而且,老实说,我认为这实际上是一段非常整齐的代码。 所以我有一个特定的用例...

最佳 Java 编程 379

java打开文件代码_Java8读取文件仅需一行代码

JDK7中引入了新的文件操作类java.nio.file.File,它包含了很多有用的方法来操作文件,比如检查文件是否为隐藏文件,或者是检查文件是否为只读文件。开发者还可以使用Files.readAllBytes(Path)方法把整个文件读入内存,此方法返回一个字节数组,还可以把结果传递给String的构造器,以便创建字符串输出。此方法确保了当读入文件的所有字节内容时,文件属性是关闭的,否则就会出...

weixin_39628405的博客 822

Java8读文件仅需一行代码

Java8读文件仅需一行代码

jhfyuf的博客 603

Java一行代码技巧_Java8读文件仅需一行代码

JDK7中引入了新的文件操作类Java.nio.file.File,它包含了很多有用的方法来操作文件,比如检查文件是否为隐藏文件,或者是检查文件是否为只读文件。开发者还可以使用Files.readAllBytes(Path)方法把整个文件读入内存,此方法返回一个字节数组,还可以把结果传递给String的构造器,以便创建字符串输出。此方法确保了当读入文件的所有字节内容时,文件属性是关闭的,否则就会出...

weixin_39562606的博客 93

Java NIO文件系统核心解析与高性能IO实践

Java NIO(Non-blocking I/O)是Java平台提供的高性能IO处理机制,其核心设计基于通道(Channel)和缓冲区(Buffer)模型,相比传统IO具有更高的吞吐量和更低的资源消耗。java.nio.file包作为NIO体系的核心组件,通过Path、Files等抽象实现了现代文件系统操作,支持符号链接、文件属性操作等高级特性。在分布式系统、大数据处理等需要高性能文件IO的场景中,NIO的文件内存映射(MappedByteBuffer)和异步通道(AsynchronousFileChan

weixin_30617737的博客 409

一种分页读取文件的方式(JDK8)

话不多说,直接上代码 import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; import ja...

CrazyTiger的博客 1374

Files.readString(path, StandardCharsets.UTF_8);提示找不到符号的解决方案

Files.readString(path, StandardCharsets.UTF_8);提示找不到符号: 符号: 方法 readString(java.nio.file.Path,java.nio.charset.Charset) 位置: 类 java.nio.file.Files

朱茂强的博客 2844

java进阶笔记之Files文件工具类

简介 Files 是JDK1.7 之后系统封装的对文件操作的工具类 . 示例 源码简析 ps: 直接调用FileSystemProvider方法实现的简单逻辑将不再注释 , 可以查看上篇: java进阶笔记之FileSystemProvider . 重要方法 walkFileTree 遍历整个文件/文件夹树. 如果读取属性时发生IO异常则调用FileVisitor#visitFileFailed方法. ps: 默认实现是SimpleFileVisitor , 直接抛出异常. 也可以自定义实现,一般是

huitoukest的专栏 605

Java深入解析篇十七之NIO.2详解

Java NIO.2(New I/O 2)是 JDK 7 引入的文件系统 API 增强,对应 JEP 106。它解决了 类长期存在的诸多不足: 设计原则 原则 说明 不可变性 Path 对象创建后不可修改 异常驱动 操作失败抛出具体 IOException 子类 可插拔文件系统 通过 FileSystemProvider 支持 ZIP/JAR/自定义文件系统 惰性遍历 结合 Stream API 实现延迟求值 Path 接口与 Paths 工厂 Path 接口核心概念

萧瑟余晖的博客 318
上一篇: 关于Broken pipe异常的一点学习记录
下一篇: 算法学习之:Raft-分布式一致性/共识算法
Jack_abu
博客等级 码龄10年 633粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_abu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值