使用PrintWriter时抛出FileNotFoundException异常,寻求技术解决方案
解决Java中getResource()获取路径导致的FileNotFoundException问题
你遇到的问题根源在于错误地将URL字符串直接传给了File构造器。getResource("save.txt")返回的是一个URL对象,调用它的toString()方法会得到类似file:/xxx/xxx.txt的URL格式路径,但File类需要的是本地文件系统的原生路径(不带file:前缀),系统会把整个URL字符串当作文件路径去查找,自然找不到对应的文件。
下面给你两种可靠的解决方案:
方案一:通过URI转换(推荐,自动处理特殊字符)
使用URL.toURI()方法将URL转换为URI,再用URI创建File对象,这种方式能自动处理路径中的编码字符(比如你路径里的%20对应空格):
try { // 从资源URL获取URI,再构建File对象 File saveFile = new File(getResource("save.txt").toURI()); PrintWriter writer = new PrintWriter(saveFile); writer.println("level:" + level); writer.println("coins:" + coins); writer.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (URISyntaxException e) { // 处理URI格式异常 e.printStackTrace(); }
方案二:解码URL路径
如果不想处理URI的异常,可以获取URL的路径后进行URL解码,把编码后的特殊字符(比如%20)还原成原生字符:
import java.net.URLDecoder; import java.nio.charset.StandardCharsets; // ... try { // 获取URL路径并解码 String rawPath = getResource("save.txt").getPath(); String decodedPath = URLDecoder.decode(rawPath, StandardCharsets.UTF_8.name()); PrintWriter writer = new PrintWriter(new File(decodedPath)); writer.println("level:" + level); writer.println("coins:" + coins); writer.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
额外注意事项
如果save.txt是你项目类路径下的资源文件,需要注意:
- 当项目打包成JAR后,类路径里的文件是只读的,无法直接写入。如果是要保存用户的游戏进度(比如level和coins),更合理的做法是把保存文件放在用户的专属目录下,比如:
// 创建用户主目录下的Jumpo文件夹 File gameSaveDir = new File(System.getProperty("user.home"), "Jumpo"); gameSaveDir.mkdirs(); // 自动创建不存在的目录 File saveFile = new File(gameSaveDir, "save.txt"); // 后续写入逻辑和之前一致 try (PrintWriter writer = new PrintWriter(saveFile)) { writer.println("level:" + level); writer.println("coins:" + coins); // 用try-with-resources可以自动关闭writer,不用手动调用close() } catch (FileNotFoundException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Salsa Gal
相关产品推荐
相关产品推荐

