为何我的FileOutputStream将文件保存到错误位置?
问题分析与修复方案
你遇到的问题核心在于错误地将输入流对象转换成字符串当作文件路径,这也是为什么会生成java.io.BufferedInputStream@11b1857c这种奇怪文件名的原因。
错误原因拆解
GameReader.class.getResourceAsStream("MO.data")这个方法的作用是读取资源文件的输入流,它返回的是一个InputStream对象,而非文件路径字符串。当你用String.valueOf()把这个流对象转成字符串时,其实调用的是InputStream的默认toString()方法,输出格式就是[类名]@[哈希码],这完全不是你想要的MO.data文件路径。
修复方案
要正确写入src/files/MO.data文件,你需要先获取到这个文件的实际路径,而非输入流。结合你的文件结构(src/logic/saver.class调用src/files/GameReader.class所在路径的MO.data),可以这样修改代码:
try { // 通过GameReader类获取MO.data的资源URL URL moDataUrl = GameReader.class.getResource("MO.data"); if (moDataUrl == null) { System.err.println("找不到MO.data文件,请检查文件路径是否正确"); return false; } // 将URL转换为File对象 File moDataFile = new File(moDataUrl.toURI()); // 打开文件输出流并写入对象 FileOutputStream fileOut = new FileOutputStream(moDataFile); ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(fileOut)); objectOut.writeObject(map); objectOut.close(); // 关闭流,确保数据写入完成 System.out.println("File saved and closed!"); return true; } catch (IOException | URISyntaxException e) { e.printStackTrace(); return false; }
额外优化建议
- 可以使用try-with-resources语法自动关闭流,避免资源泄漏:
try (FileOutputStream fileOut = new FileOutputStream(moDataFile); ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(fileOut))) { objectOut.writeObject(map); System.out.println("File saved and closed!"); return true; } catch (IOException | URISyntaxException e) { e.printStackTrace(); return false; } - 如果项目打包成JAR文件,
getResource()返回的URL会指向JAR内部资源,此时无法直接写入JAR内的文件,需要将MO.data放在JAR外部目录,用绝对路径或相对路径访问。 - 确保程序拥有
src/files/目录的写入权限,避免因权限不足导致写入失败。
内容的提问来源于stack exchange,提问作者Ryan Sangha
相关产品推荐
相关产品推荐

