Files.readAllLines 必须显式处理 IOException,应使用 try-catch 捕获;需显式指定 StandardCharsets.UTF_8 防乱码;大文件易 OOM,建议改用 Files.lines 或 BufferedReader;路径推荐用 Paths.get 构造 Path。

Files.readAllLines 读取文件时抛出 IOException 怎么处理
这个方法不吞异常,必须显式处理。不加 try-catch 或声明 throws IOException,编译直接报错。
常见写法是用 try-with-resources 包一层,但注意:Files.readAllLines 本身不实现 AutoCloseable,不需要、也不能放进去关流——它内部自动管理资源。
- 正确做法:外层包
try-catch捕获IOException,比如文件不存在、权限不足、编码不匹配 - 别写成
try (var lines = Files.readAllLines(...))—— 编译不过,readAllLines返回的是List<String>,不是可关闭资源 - 如果确定文件一定存在且路径可控,可以用
UncheckedIOException包装后抛运行时异常,避免层层 throws
中文乱码?默认编码不是 UTF-8
Files.readAllLines 在没指定编码时,用的是 StandardCharsets.UTF_8 吗?不是。它用的是 Charset.defaultCharset(),也就是当前 JVM 的默认编码,Windows 上常是 GBK,Linux/macOS 一般是 UTF-8。
一旦 txt 是 UTF-8 无 BOM 写的,但在 Windows 上用默认编码读,中文就变 ???。
立即学习“Java免费学习笔记(深入)”;
- 务必显式传入
StandardCharsets.UTF_8(或对应编码):Files.readAllLines(path, StandardCharsets.UTF_8) - 不要依赖系统默认值,尤其部署环境和开发环境不一致时,问题必现
- 如果不确定源文件编码,先用工具(如
file -i filename.txt或 VS Code 右下角编码提示)确认,再硬编码进参数
大文件用 readAllLines 会 OOM
这个方法把整份文件所有行一次性加载进内存,返回 List<String>。几 MB 的日志文件可能没事,但几十 MB 或带长文本的文件,很容易触发 OutOfMemoryError。
它适合小配置文件、初始化数据等「确定体积小」的场景,不是通用读文件方案。
- 超过 10MB 就该换方案:用
Files.lines(path)得到Stream<String>,配合 filter/map/limit 流式处理 - 需要逐行处理且不依赖随机访问时,用
BufferedReader+readLine()更可控 -
readAllLines返回的List是不可变的(底层是ArrayList,但内容不可修改),想改内容得 new 一个新 list
路径传 String 还是 Path?推荐后者
方法签名是 readAllLines(Path path, Charset cs),不接受 String。有人图省事拼字符串路径再转 Path,结果在 Windows 上遇到反斜杠 转义问题,或 Linux 上路径含空格失败。
别自己拼,用标准 API 构造 Path。
- 从 classpath 读:
Paths.get(YourClass.class.getResource("/data.txt").toURI()) - 从绝对路径读:
Paths.get("/home/user/file.txt")(Linux/macOS)或Paths.get("C:\temp\file.txt") - 相对路径建议用
Paths.get(".").resolve("data.txt"),比new File("data.txt").toPath()更符合 NIO 风格 - 传进去前先
Files.exists(path)判断,避免NoSuchFileException打乱逻辑
最常被忽略的是编码和文件大小这两个点:一个导致读出来是乱码,一个导致上线后某天突然挂掉。传参不写编码、不评估体积,等于埋了两个静默雷。










