JDK 內建 java.beans.XMLEncoder / XMLDecoder 提供人類可讀、跨版本相容、無需第三方依賴的物件持久化方案,適合配置檔、狀態快照、簡單數據交換場景。
package com.imct.util;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 使用 XML 文件存取可序列化物件的工具類
* @author 殷晉
* @version 1.0
*/
public class ObjectToXMLUtil {
/**
* 將可序列化物件編碼為 XML 文件
* @param obj 目標物件(需實現 Serializable)
* @param fileName 完整路徑文件名
* @throws FileNotFoundException 文件路徑無效
* @throws IOException I/O 錯誤
*/
public static void objectXMLEncoder(Object obj, String fileName)
throws FileNotFoundException, IOException {
File file = new File(fileName);
// 自動建立父目錄
File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
try (FileOutputStream fos = new FileOutputStream(file);
XMLEncoder encoder = new XMLEncoder(fos)) {
encoder.writeObject(obj);
encoder.flush();
}
}
/**
* 從 XML 文件解碼物件列表(支援多物件順序寫入)
* @param fileName 完整路徑文件名
* @return 物件列表(按寫入順序)
* @throws FileNotFoundException 文件不存在
* @throws IOException I/O 錯誤
*/
@SuppressWarnings("unchecked")
public static List<Object> objectXMLDecoder(String fileName)
throws FileNotFoundException, IOException {
List<Object> objList = new ArrayList<>();
File file = new File(fileName);
try (FileInputStream fis = new FileInputStream(file);
XMLDecoder decoder = new XMLDecoder(fis)) {
Object obj;
while ((obj = decoder.readObject()) != null) {
objList.add(obj);
}
}
return objList;
}
}
mkdirs() 避免因目錄不存在拋出異常。null,兼容單物件與多物件場景。// 寫入
User user = new User("張三", 25);
List<User> users = Arrays.asList(user, new User("李四", 30));
ObjectToXMLUtil.objectXMLEncoder(users, "data/users.xml");
// 讀取
List<Object> list = ObjectToXMLUtil.objectXMLDecoder("data/users.xml");
for (Object o : list) {
System.out.println(o); // 需目標類重寫 toString()
}
| 優點 | 缺點 |
|---|---|
| 零依賴、JDK 內建、XML 可讀、版本容錯性強 | 效能、體積遜於二進制/JSON;不支援循環引用;需 JavaBean 慣例(無參建構子 + getter/setter) |
建議場景:配置持久化、會話狀態存檔、小型數據交換、測試數據準備。高性能/大數據場景請使用 Protobuf、Kryo、Jackson JSON。