本地正常但Heroku部署时出现FileNotFoundException的Java API问题
问题原因分析
1. 硬编码路径与Heroku部署环境不匹配
本地开发时项目源码目录存在./src/main/java/org/test/resources/路径,但Heroku部署Java应用时,会将代码打包成JAR/WAR文件运行,不存在源码的src目录结构,直接访问该路径必然抛出FileNotFoundException。
2. 未确保父目录存在
即使路径正确,代码中直接通过FileWriter创建文件时,如果父目录不存在,JVM不会自动创建父目录,也会触发该异常。
3. Heroku文件系统权限限制
Heroku的文件系统是临时且受限制的,只有/tmp目录允许读写,其他目录(如默认工作目录)可能没有写入权限或路径不存在。
解决方法
方案一:使用Java标准临时文件API(推荐)
Java提供的File.createTempFile()方法会自动使用系统临时目录(Heroku上对应/tmp),无需硬编码路径,同时自动处理目录创建问题:
private static File makeTempFile(String data, String fileName) { try { // 创建临时文件,前缀为temp_+fileName,后缀为.json,放在系统临时目录 File tempFile = File.createTempFile("temp_" + fileName, ".json"); try (FileWriter writer = new FileWriter(tempFile)) { writer.write(formatJson(data)); System.out.println(tempFile.getAbsolutePath() + " created"); // 标记JVM退出时自动删除文件(可选,也可在方法结束后手动删除) tempFile.deleteOnExit(); return tempFile; } } catch (Exception e) { System.out.println("Unable to create tempfile"); e.printStackTrace(); return null; } }
方案二:手动指定Heroku可写目录并确保父目录存在
如果需要自定义路径,必须使用Heroku允许的/tmp目录,并且先检查创建父目录:
// 通过系统属性获取临时目录,兼容本地和Heroku环境 private static final String BASE_PATH = System.getProperty("java.io.tmpdir"); private static File makeTempFile(String data, String fileName) { File file = new File(BASE_PATH, "temp_" + fileName + ".json"); // 确保父目录存在 File parentDir = file.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } try (FileWriter writer = new FileWriter(file)) { writer.write(formatJson(data)); System.out.println(file.getAbsolutePath() + " created"); return file; } catch (Exception e) { System.out.println("Unable to create tempfile"); e.printStackTrace(); return null; } }
额外注意事项
- Heroku的临时文件系统会在dyno重启时被清空,不要依赖临时文件存储持久化数据。
- 手动删除临时文件时,确保在文件使用完成后执行,避免出现文件被占用的问题。
内容的提问来源于stack exchange,提问作者Rikkarth
相关产品推荐
相关产品推荐

