编程新手读文件遇FileNotFoundException但文件存在,求排查及替代方法
问题排查与替代方案
兄弟,我刚瞅了你的代码,咱们一步步揪出这个FileNotFoundException的问题——虽然你说文件就在打印的绝对路径里,但新手常踩的坑可不少,给你列几个可能性:
可能的问题原因
- 大小写敏感坑:Windows系统文件名不区分大小写,但Linux/macOS是认死理的。比如你代码里写的是
trees.txt,实际文件要是叫Trees.txt或者TREES.TXT,非Windows系统直接就找不到了。 - 工作目录错位:你用
new File("").getAbsolutePath()打印的是JVM的当前工作目录,但IDE(比如IntelliJ、Eclipse)的默认工作目录可能不是你想的项目根目录。比如你把文件放在项目根目录,但IDE偷偷把工作目录设成了src文件夹,这时候自然找不到。你可以先把路径改成绝对路径试试(比如C:/myProject/trees.txt或者/home/me/myProject/trees.txt),验证下是不是这个问题。 - 权限不够:文件存在但你的程序没权限读。比如Linux/macOS下文件权限是
rw-------,只有所有者能读,而你运行程序的用户没权限,也会抛这个异常。Windows的话右键看文件属性,检查“读取权限”有没有开。 - 隐形双重扩展名:Windows默认会隐藏已知文件的扩展名,比如你看到的
trees.txt,实际可能是trees.txt.txt(保存的时候手滑多打了个.txt)。打开文件资源管理器的“显示文件扩展名”选项,看看真实文件名到底是什么。
其他更顺手的文件读取方式
Java现在有好多比FileReader+Scanner更简洁的方法,给你推荐几个常用的:
1. Java NIO Files类(Java 7+首选)
这是最现代的写法,一行读全量,还能自动关资源,不用手动处理流:
import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public void readFileWithFiles() { String filename = "trees.txt"; try { // 把所有行读到List里,适合小文件 List<String> lines = Files.readAllLines(Paths.get(filename)); lines.forEach(System.out::println); } catch (Exception e) { e.printStackTrace(); } }
要是读大文件怕占内存,就用流式读取:
import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public void readLargeFileWithFiles() { String filename = "trees.txt"; // try-with-resources自动关闭流 try (Stream<String> lines = Files.lines(Paths.get(filename))) { lines.forEach(System.out::println); } catch (Exception e) { e.printStackTrace(); } }
2. BufferedReader(传统IO,高效逐行读)
比FileReader快,因为带缓冲区,同样用try-with-resources自动关:
import java.io.BufferedReader; import java.io.FileReader; public void readFileWithBufferedReader() { String filename = "trees.txt"; try (BufferedReader br = new BufferedReader(new FileReader(filename))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } }
3. 指定编码的Scanner写法
有时候文件编码不对也会出问题,给Scanner指定编码(比如UTF-8)更稳妥:
import java.io.File; import java.util.Scanner; public void readFileWithScannerEncoded() { String filename = "trees.txt"; try (Scanner parser = new Scanner(new File(filename), "UTF-8")) { while (parser.hasNextLine()) { System.out.println(parser.nextLine()); } } catch (Exception e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Sampreeth Amith Kumar
相关产品推荐
相关产品推荐

