首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java 反序列化 ArrayList 遇到 EOFException:文件為空、流未關閉或類不匹配

     編輯:程式設計疑難解答

Java 反序列化 ArrayList 遇到 EOFException:文件為空、流未關閉或類不匹配

使用 ObjectInputStream 讀取 ArrayList 時拋出 EOFException,常見四大原因:

1. 文件為空或損壞

首次運行時文件不存在或長度為 0,直接調用 readObject() 會拋出 EOF。解決:讀取前檢查 file.length() > 0。

2. 寫入時未正確關閉流

ObjectOutputStream 緩衝數據,若程式異常退出或未調用 close(),文件尾部不完整。務必使用 try-with-resources:

try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
    oos.writeObject(list);
} // 自動 close,刷新緩衝區

3. 類定義變更導致 serialVersionUID 不匹配

若 Message 類修改了字段但未顯式聲明 private static final long serialVersionUID = 1L;,反序列化會拋 InvalidClassException(有時包裹為 EOF)。

4. 同一文件多次寫入未重置流

若多次 writeObject 追加到同一文件,讀取時需對應次數 readObject,且必須使用 new ObjectInputStream(new FileInputStream(file)) 重新打開流,不能復用舊流。

健壯的讀寫模板

// 寫入
public void write(List list) {
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
        oos.writeObject(list);
    } catch (IOException e) { e.printStackTrace(); }
}

// 讀取
public List read() {
    if (!file.exists() || file.length() == 0) return new ArrayList<>();
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
        @SuppressWarnings("unchecked")
        List list = (List) ois.readObject();
        return list;
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
        return new ArrayList<>();
    }
}

遵循「寫入即關閉、讀取前判空、類版本固化」三原則,可消除 99% 的 EOFException。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved