byte[] + 唯一 recordId(從 1 遞增,刪除後不重用)。// 開啟/建立
RecordStore rs = RecordStore.openRecordStore("MyData", true);
// 寫入
byte[] data = "content".getBytes();
int id = rs.addRecord(data, 0, data.length);
// 讀取
byte[] buf = new byte[rs.getRecordSize(id)];
rs.getRecord(id, buf, 0);
String content = new String(buf, 0, buf.length);
// 更新
rs.setRecord(id, newData, 0, newData.length);
// 刪除
rs.deleteRecord(id); // id 永久失效
// 關閉
rs.closeRecordStore();
// 刪除整個 Store
RecordStore.deleteRecordStore("MyData");
解決「刪除後 ID 不連續」導致 for (i=1; i<=numRecords; i++) 拋異常的問題:
RecordEnumeration re = rs.enumerateRecords(null, null, false);
while (re.hasNextElement()) {
byte[] rec = re.nextRecord(); // 取資料
int id = re.nextRecordId(); // 取 ID(可用於更新/刪除)
}
re.destroy(); // 釋放資源
class NameComparator implements RecordComparator {
public int compare(byte[] rec1, byte[] rec2) {
String s1 = new String(rec1), s2 = new String(rec2);
int cmp = s1.compareTo(s2);
return (cmp == 0) ? EQUIVALENT : (cmp < 0 ? PRECEDES : FOLLOWS);
}
}
// 使用
RecordEnumeration re = rs.enumerateRecords(null, new NameComparator(), false);
class KeywordFilter implements RecordFilter {
private String keyword;
public KeywordFilter(String kw) { keyword = kw.toLowerCase(); }
public boolean matches(byte[] candidate) {
return new String(candidate).toLowerCase().indexOf(keyword) >= 0;
}
}
// 使用
RecordEnumeration re = rs.enumerateRecords(new KeywordFilter("meeting"), null, false);
可組合:enumerateRecords(filter, comparator, false) → 先過濾後排序。
單條記錄:時間戳(13位)#約會內容 → System.currentTimeMillis() + "#" + desc
刪除標記:"#DELETED#" + 原記錄(保持 ID 不變,避免枚舉亂序)。
// 新增
public void addAppointment(String desc) {
String rec = System.currentTimeMillis() + "#" + desc;
rs.addRecord(rec.getBytes(), 0, rec.length());
}
// 列表(跳過已刪除)
public Vector listAppointments() {
Vector vec = new Vector();
RecordEnumeration re = rs.enumerateRecords(null, new TimeComparator(), false);
while (re.hasNextElement()) {
String s = new String(re.nextRecord());
if (!s.startsWith("#DELETED#")) vec.addElement(parse(s));
}
re.destroy();
return vec;
}
// 刪除(軟刪除)
public void deleteAppointment(int recordId) {
byte[] old = rs.getRecord(recordId);
rs.setRecord(recordId, ("#DELETED#" + new String(old)).getBytes(), 0, old.length);
}
DateField (日期時間) + TextField (內容) + 保存命令ChoiceGroup (MULTIPLE) 勾選多條,刪除命令批次軟刪除DateField、TextField、ChoiceGroup 狀態變化,即時更新模型| 場景 | 建議 |
|---|---|
| 記錄數 > 500 | 分多個 Store(按月/類別),避免單 Store 索引過大 |
| 頻繁查詢 | 建立記憶體索引(ID→關鍵字)輔助 Filter,減少 byte[]→String 轉換 |
| 大數據塊 (>8 KB) | 拆分多條記錄,或改用檔案系統 (JSR 75 FileConnection) |
| 多 MIDlet 共享 | openRecordStore(name, vendor, suite) 跨套件存取,需簽名權限 |
| 備份/遷移 | 導出為 CSV/JSON 上傳伺服器,或 PC 端工具讀取 RMS 檔案 |
closeRecordStore() 必須在 destroyApp() 呼叫,否則資料損壞。synchronized 或單線程隊列。getNextRecordID()。RMS 是 J2ME 唯一標準持久化方案,雖無 SQL、無索引,但掌握枚舉器+比較器+過濾器三板斧,配合軟刪除、版本控制、跨套件共享,足以支撐通訊錄、遊戲存檔、離線地圖等中型應用。記住:**資料結構設計決定查詢效能,byte[] 序列化設計決定儲存密度。**