Java如何仅通过文件名访问文件,解决NoSuchFileException及跨设备兼容问题
报错的核心原因
你当前使用的Paths.get("fileName.txt")是相对路径写法,定位文件的基准是JVM进程启动时的工作目录,既不是你的源码所在目录,也不是项目的资源存放目录。只要启动应用时的工作目录和fileName.txt的实际存放位置不一致,就会直接抛出NoSuchFileException,和你写的文件名完全无关。
另外你贴的原代码里FileSystem fs FileSystems.getDefault()存在语法错误,变量声明时漏了等号,补全后也不解决路径定位的根本问题。
跨设备兼容的落地方案
所有方案都不需要硬编码文件的绝对路径,可直接在不同开发设备上复用:
- 方案1(推荐,适配开发+打包运行全场景):将目标文件放入项目标准资源目录,用类加载器定位
对Maven、Gradle这类标准结构的项目,把fileName.txt放到src/main/resources根目录下,读取逻辑改为:
这种写法的路径基准是类加载器对应的资源根目录,不管你在IDE里启动、打包成Jar运行、还是换其他笔记本,只要项目结构一致,就能精准定位文件,完全不受工作目录变化的影响。// 通过类加载器定位资源路径,无任何硬编码绝对路径 URL resourceUrl = getClass().getClassLoader().getResource("fileName.txt"); Path fileIn = Paths.get(resourceUrl.toURI()); - 方案2(仅适配本地开发场景):显式拼接项目根目录的相对路径
如果不需要把文件随项目打包,可把fileName.txt放到项目根目录(和src目录同级的位置),读取时主动定位项目根再拼路径:
注意:这种写法的前提是启动项目时的工作目录刚好在项目根路径下,从其他目录启动依然会触发文件找不到的异常,适合本地临时开发场景。// 定位当前项目的根目录(即构建配置文件所在目录) Path projectRoot = Paths.get("").toAbsolutePath(); Path fileIn = projectRoot.resolve("fileName.txt"); - 方案3(适配多环境灵活部署):路径配置化
把文件的存放位置做成配置项,写入项目的配置文件中,代码里直接读取配置值拼路径:
换设备部署时只需要修改配置文件里的相对路径值,完全不需要改动代码逻辑,从根源上避免硬编码。// 从配置文件读取文件相对路径,比如配置值写"runtime/fileName.txt" String fileRelativePath = configReader.getProperty("target.file.path"); Path fileIn = Paths.get(fileRelativePath);
避坑提醒:不要在代码里直接写相对于源码位置的相对路径,当项目打包成可执行Jar后,源码目录结构会被打散,这类相对路径会完全失效。优先选择类加载器读取资源的写法,这是Java生态跨环境定位文件的通用标准方案。
内容的提问来源于stack exchange,提问作者Pat
相关产品推荐
相关产品推荐

