| 類別/介面 | 用途 |
RecordStore | 主要操作類別:開啟/建立/刪除/列舉/寫入/讀取/更新/刪除記錄 |
RecordEnumeration | 遍歷記錄集合,支援比較器排序、過濾器篩選 |
RecordComparator | 自訂排序邏輯 (介面) |
RecordFilter | 自訂篩選邏輯 (介面) |
RecordListener | 記錄變更通知 (介面) |
基本操作流程與程式碼範例
1. 開啟/建立 Record Store
RecordStore rs = null;
try {
rs = RecordStore.openRecordStore("TestRecordSet", true); // true = 不存在則建立
} catch (RecordStoreException e) {
// 處理儲存空間不足、名稱衝突等
}
2. 新增記錄
// 準備資料:自訂序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF("UserName");
dos.writeInt(12345);
dos.writeLong(System.currentTimeMillis());
// ... 其他欄位
byte[] recordData = baos.toByteArray();
// 寫入
int recordId = rs.addRecord(recordData, 0, recordData.length);
// recordId 為 1-based 遞增識別碼
3. 讀取記錄
// 讀取單筆
byte[] data = rs.getRecord(recordId); // 拋出 InvalidRecordIDException 若不存在
// 或
int len = rs.getRecord(recordId, buffer, offset); // 讀入預分配緩衝區
// 解析
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
String name = dis.readUTF();
int id = dis.readInt();
long time = dis.readLong();
4. 更新與刪除
// 更新 (完整覆寫)
rs.setRecord(recordId, newData, 0, newData.length);
// 刪除
rs.deleteRecord(recordId);
5. 列舉與篩選 (RecordEnumeration)
// 取得所有記錄 ID 列舉
RecordEnumeration re = rs.enumerateRecords(null, null, false); // 無過濾、無排序、不保持最新快照
while (re.hasNextElement()) {
int id = re.nextRecordId();
byte[] data = rs.getRecord(id);
// 處理...
}
// 使用過濾器:只取名稱為 "Admin" 的記錄
RecordFilter adminFilter = new RecordFilter() {
public boolean matches(byte[] candidate) {
try {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(candidate));
return "Admin".equals(dis.readUTF());
} catch (Exception e) { return false; }
}
};
RecordEnumeration filtered = rs.enumerateRecords(adminFilter, null, false);
6. 關閉與資源釋放
rs.closeRecordStore();
// 應用結束時務必呼叫,確保資料刷新至儲存體
進階主題與最佳實踐
記錄 ID 管理
- ID 為 1-based 遞增,刪除後不會重複使用
- 長期運行應用可能耗盡 ID 空間 (理論上限 2^31-1),需定期重建 Store
資料結構序列化策略
| 策略 | 優點 | 缺點 | 適用場景 |
| DataOutputStream (writeUTF/writeInt...) | 標準、跨平台、支援變長字串 | 需對應讀取順序、Schema 演進需自行處理 | 簡單結構、固定欄位 |
| 自訂二進位格式 (固定長度) | 讀寫快、體積小 | 字串長度固定、擴充困難 | 高效能、大量記錄 |
| JSON 序列化 (org.json.me) | 自描述、易除錯、Schema 彈性 | 體積較大、解析較慢 | 複雜巢狀結構、需與網路交換相容 |
效能優化
- 批次寫入:累積多筆再寫入 (但 RMS 無交易機制,單筆原子)
- 索引機制:維護獨立索引 Store (如
name→recordId 映射) 加速查詢
- 快取熱點資料記憶體中,減少 RMS I/O
多執行緒安全
RecordStore 方法為**同步化**,可安全多執行緒存取。但複合操作 (如「讀取→修改→寫回」) 需應用層自行同步。
空間管理與異常處理
- 捕捉
RecordStoreFullException:提示使用者清理或移除舊資料
- 定期檢查
rs.getSize() / rs.getSizeAvailable()
- 實作 LRU 淘汰策略自動清理過期記錄
完整範例:簡易通訊錄 MIDlet
public class AddressBook {
private static final String STORE_NAME = "AddressBook";
private RecordStore rs;
public void open() throws RecordStoreException {
rs = RecordStore.openRecordStore(STORE_NAME, true);
}
public int addContact(String name, String phone) throws RecordStoreException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(name);
dos.writeUTF(phone);
return rs.addRecord(baos.toByteArray(), 0, baos.size());
}
public Contact getContact(int id) throws Exception {
byte[] data = rs.getRecord(id);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
return new Contact(dis.readUTF(), dis.readUTF());
}
public void listContacts(ContactHandler handler) throws RecordStoreException {
RecordEnumeration re = rs.enumerateRecords(null, null, false);
while (re.hasNextElement()) {
int id = re.nextRecordId();
handler.handle(id, getContact(id));
}
}
public void close() throws RecordStoreException {
rs.closeRecordStore();
}
}
總結
RMS 是 J2ME 應用持久化的核心基礎設施。掌握 RecordStore 基本操作、RecordEnumeration 靈活查詢、序列化策略選擇與空間管理,即可構建可靠的本地資料層,支援離線操作、設定保存、快取等關鍵功能。
- 上一篇文章: J2ME/J2EE 架構下 JSON 資料交換框架設計與實作分析
- 下一篇文章: J2ME 網路程式設計深度解析:Generic Connection Framework 與 HTTP 實戰
Copyright ©
程式碼之家 All Rights Reserved