Java序列化HashMap时注释写入代码后出现EOFException的原因
Java HashMap序列化持久化问题:EOFException 原因与修复
问题根源
你遇到的EOFException是因为打开ObjectOutputStream(底层依赖FileOutputStream)时,默认会直接清空目标文件的所有内容。即使你注释了out.writeObject(mapToWrite);语句,文件在打开写流的瞬间就已经被清空,后续读取自然会因为文件为空触发EOF异常。
原代码的核心错误:
- 同时对同一个文件打开读流和写流,写流初始化时就覆盖了原有文件内容
- 读取操作在写流打开之后,此时文件已空,无法读取到有效序列化数据
解决方案
拆分读取和写入逻辑,程序启动时加载数据,结束前保存数据,避免同时操作同一文件的读写流;同时处理文件不存在或为空的初始场景。
修正后的代码示例
1. 加载HashMap的方法
public static HashMap<String, Integer> loadProgressMap() { File storageFile = new File("Progress/HashMapStorage.ser"); // 确保存储目录存在,避免因目录缺失抛出异常 storageFile.getParentFile().mkdirs(); try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(storageFile))) { return (HashMap<String, Integer>) in.readObject(); } catch (FileNotFoundException | EOFException e) { // 文件不存在或为空时,返回空Map初始化 return new HashMap<>(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return new HashMap<>(); } }
2. 保存HashMap的方法
public static void saveProgressMap(HashMap<String, Integer> progressMap) throws IOException { File storageFile = new File("Progress/HashMapStorage.ser"); storageFile.getParentFile().mkdirs(); try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(storageFile))) { out.writeObject(progressMap); } }
3. 业务逻辑使用示例
public static void main(String[] args) throws IOException { // 程序启动时加载持久化数据 HashMap<String, Integer> progressMap = loadProgressMap(); // 执行业务操作:更新观看进度 progressMap.put("one", 1); progressMap.put("two", 2); // 程序结束前保存数据(可放在退出钩子或业务流程末尾) saveProgressMap(progressMap); // 验证跨会话读取 HashMap<String, Integer> loadedMap = loadProgressMap(); System.out.println(loadedMap); // 输出 {one=1, two=2} }
关键注意事项
- 使用
try-with-resources语法自动管理流资源,避免手动关闭遗漏导致的资源泄漏 - 提前创建存储目录,防止因目录不存在抛出
IOException - 读取时捕获
FileNotFoundException和EOFException,处理首次运行无数据的场景
内容的提问来源于stack exchange,提问作者Jacob Schweiger
相关产品推荐
相关产品推荐

