Java读取txt文件报错,核心原因多集中在文件路径错误、编码不匹配、文件不存在或权限不足,解决方案需根据具体异常类型对症下药。
java读取txt文件报错:常见异常及解决步骤
遇到报错先别慌,看异常类型就能定位八成问题,下面从最常出现的几个异常入手,逐一拆解。
FileNotFoundException:文件找不到
这个异常一出现,十有八九是路径写错了,路径问题分两种:
- 绝对路径写死:比如
C:/myfile/data.txt,在本地测试可能没问题,但部署到服务器或换台机器就崩。绝对路径缺乏移植性,应当避免在代码中硬编码。 - 相对路径迷路:相对路径是相对于当前工作目录的,而工作目录取决于启动方式,在IDE里运行和用
java -jar运行,工作目录可能不同。
解决方案:
- 把文件放在classpath下(如
resources目录),用getClass().getClassLoader().getResourceAsStream("data.txt")读取,这样路径不依赖工作目录。 - 如果必须用外部文件,建议通过配置文件或环境变量传入路径,而不是在代码里写死。
- 使用
Paths.get()和Files.exists()先判断文件是否存在,再读取。
IOException:读取过程出错
IOException是个笼统的异常,可能由磁盘空间不足、文件被占用或网络中断引起。多数情况下是流没有正确关闭,导致资源泄露。
标准做法:
- 使用try-with-resources语句,它会在代码块结束后自动关闭流,避免手动关闭遗漏。
- 如果必须使用传统
try-catch-finally,务必在finally里关闭流,并且对关闭操作本身也捕获异常,防止关闭失败覆盖原始异常。
UnsupportedEncodingException:编码不匹配
读取txt文件时没指定编码,系统会使用默认编码(如Windows的GBK),而文件可能是UTF-8,结果就是乱码或直接报错。
根本原因:Java的FileReader默认使用系统编码,无法指定编码,极易导致编码问题,所以业界共识是:永远不要用FileReader读取txt文件,除非你百分百确定文件编码与系统一致。
替代方案:使用InputStreamReader配合FileInputStream,显式指定编码,比如new InputStreamReader(new FileInputStream("file.txt"), "UTF-8")。
java读取txt文件乱码:编码设置的正确方式
乱码是读取txt文件时最让人头疼的问题之一,但解决起来并不复杂。关键在于读取时指定和文件一致的编码。
如何确定文件编码
- 用记事本打开txt文件,点击“另存为”,看底部编码下拉框显示的是什么,常见的有UTF-8、ANSI(即GBK)、Unicode、UTF-16。
- 在Linux下可以用
file -i filename.txt命令查看编码。 - 如果你不确定,可以尝试先用UTF-8读取,如果发现乱码,再用GBK尝试。据统计,绝大多数现代txt文件(尤其是从网络下载或跨平台传输的)都是UTF-8编码。
强制指定编码读取
// 推荐:使用BufferedReader包装InputStreamReader
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("data.txt"), "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每一行
}
}
注意:FileReader没有参数可以指定编码,所以必须绕道InputStreamReader,这个写法虽然多了一层,但保证了编码可控。
乱码后的补救
如果已经读取出乱码,且数据是重要内容,可以尝试用new String(str.getBytes("ISO-8859-1"), "UTF-8")之类的转换技巧,但这只是经验性补救,成功率不高。最根本的办法是读取时就用正确编码。
java读取txt文件路径问题:绝对路径 vs 相对路径
路径问题引起的报错占了很大比例,这里把路径的几种写法说清楚,你按需选择。
绝对路径
- 优点:定位明确,不受工作目录影响。
- 缺点:硬编码导致不易移植,一旦改变文件位置就得改代码。
- 适用场景:临时调试或明确知道文件绝对位置,且不会变动。
相对路径
- 相对于当前工作目录(即
System.getProperty("user.dir"))。 - 在IDE中运行,工作目录通常是项目根目录;在命令行运行,工作目录是执行命令的目录。
- 容易踩坑:很多人以为相对路径是相对于classpath或相对于当前类文件,其实不是。
建议做法:
- 把文件放在resources目录下,用
getResourceAsStream读取,这是最稳妥的方式,无论你怎么打包部署,文件都能找到。 - 如果文件必须放在外部,通过启动参数传入路径,比如
,然后在代码中读取参数。java -jar myapp.jar --file.path=/opt/data/input.txt
跨平台路径分隔符
Windows用,Linux和macOS用。Java提供了File.separator或Paths.get()来自动处理分隔符,不用手写"\"或。
// 用Paths.get自动适应系统
Path path = Paths.get("myfolder", "data.txt");
// 或者用File.separator
String path = "myfolder" + File.separator + "data.txt";
java读取txt文件正确代码示例:从入门到实战
这里给出三种主流写法,你根据场景选择。
BufferedReader + InputStreamReader(推荐日常使用)
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("input.txt"), "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
优点:逐行读取,内存友好,适合大文件;可以指定编码。
缺点:代码稍显啰嗦。
Files.readAllLines(适合小文件)
List<String> lines = Files.readAllLines(Paths.get("input.txt"), StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
优点:代码简洁,一行读取所有行。
缺点:文件全部读到内存,文件过大容易OOM。业内专家指出,超过50MB的txt文件不建议用这个方法。
Scanner(适合简单解析)
try (Scanner scanner = new Scanner(new File("input.txt"), "UTF-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// 处理
}
}
优点:支持正则分隔和类型转换。
缺点:性能略低于BufferedReader,处理大文件时效率稍差。
java读取txt文件性能对比:不同方法的优劣
| 方法 | 内存占用 | 编码可控 | 代码简洁 | 大文件支持 |
|---|---|---|---|---|
| BufferedReader + InputStreamReader | 低 | 是 | 中等 | 优秀 |
| Files.readAllLines | 高(全量加载) | 是 | 简单 | 差 |
| Scanner | 低 | 是 | 中等 | 良好 |
| FileReader(不推荐) | 低 | 否 | 简单 | 良好 |
行业共识认为:对于大多数场景,BufferedReader是首选,兼顾性能与可控性,如果文件很小(几百KB),Files.readAllLines的简洁性更胜一筹。
java读取txt文件大文件处理:避免内存溢出
当txt文件超过几百MB,甚至几个GB时,读取策略必须调整。
逐行流式读取
使用BufferedReader的readLine()方法,一次只读一行,处理完再读下一行,内存里始终只有一行数据,这是处理大文件的标准做法。
使用并行流
如果文件行数巨大且需要复杂处理,可以考虑用Files.lines()返回的Stream配合parallel(),利用多核加速,但要注意线程安全和资源管理:
try (Stream<String> lines = Files.lines(Paths.get("bigfile.txt"), StandardCharsets.UTF_8)) {
lines.parallel().forEach(line -> {
// 处理逻辑,注意线程安全
});
}
注意:Files.lines()底层也是BufferedReader,而且是惰性加载,不会一次性全读入内存,配合parallel()时,一定要确保处理逻辑是线程安全的,且顺序不重要。
分块读取
如果读取的不是文本行,而是固定长度的二进制块,可以用BufferedInputStream的read(byte[])分块读取,但txt文件通常按行处理,所以分块读取不太常用。
java读取txt文件常见问题解答
读取txt文件时抛出NullPointerException,怎么排查?
当你用`getResourceAsStream()`读取文件时,如果文件不存在,返回的是`null`,后续对流操作就会抛出空指针。解决方法:在读取前判断`inputStream == null`,并给出清晰的错误提示,文件未找到,请检查路径”。
用Files.readAllLines读取大文件,结果内存溢出,怎么办?
换用`BufferedReader`逐行读取,或者使用`Files.lines()`返回的`Stream`,`Stream`是惰性加载的,不会一次性加载全部内容,如果文件超过1GB,建议使用`BufferedReader`的`readLine()`循环处理。
读取txt文件时,一部分中文正常,一部分是乱码,是什么原因?
通常是因为文件编码不统一,比如文件大部分是UTF-8,但某一段是GBK编码。这种情况少见于纯文本文件,更常见于混合编码的历史数据,你可以尝试用`CharsetDetector`(如`juniversalchardet`库)自动检测编码,或者通过与文件创建方确认实际编码来统一处理。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/544276.html



