RMS是首先在MIDP1.0中提出的,它所在的包是javax.microedition.rms,在這個包裏面總共包括四個接口、一個類和五個異常。由此可見RMS設計的非常小巧,這正是爲了滿足移動信息設備資源受限的需求。下面我們先弄清楚幾個概念。
- 什麼是持久性存儲?
持久性存儲簡單的理解就是數據不因爲程序的退出而丟失,一般我們在程序中聲明的變量都是存儲在stack或者heap上的,程序退出後這些數據會被清除以釋放資源。而存儲在RMS中的數據是不會被清除的。 - RMS的數據存儲在哪裏?
MIDP規範中沒有規定RMS的數據必須存儲在哪裏,而是由廠商來具體實現。一般存儲在非揮發性的內存空間。因此這是對程序員透明的。 - RMS的容量最小爲多少?
MIDP中規定廠商實現RMS的時候,提供的存儲空間不能小於8KB,例如筆者的Nokia 6108的RMS空間爲30KB。 - RMS中按照Record來存儲的,ID是不是等於索引?
ID和索引的區別還是很大的,ID從1開始計數,這和數組的0開始計數有一些不同。ID可以是不連續的,當一個ID標記的Record被刪除後那麼對應的ID也就變得無效了。ID是不能重複使用的。 - RMS對存儲在其中的數據格式有具體要求嗎?
答案是沒有,只要數據可以被轉換成byte[]那麼這個數據就可以存儲在RMS中,取出的時候仍然是byte[]。因此這就要求我們開發人員來描繪數據的樣子,因爲RMS只是負責把數據按照byte[]寫入和讀出。 - 在一個MIDlet套件中,RecordStore可以被共享嗎?
可以 - 一個MIDlet套件中的RecordStore可以被另外一個RecordStore訪問嗎?
在MIDP1.0中不可以,在MIDP2.0中推出了共享機制,通過共享可以實現。
上面以7個問題的形勢總結了RMS中需要注意的基本概念,下面我們看看如何使用RMS。一般初學者學習RMS的時候通常會被他們的方法給弄的不知如何下手,因爲很多方法看上去很類似。這裏我進行如下的總結,提供一些使用指南給大家。
首先讀者應該清楚RecordStore就相當於一個數據庫,你必須新建一個這樣的數據庫纔可以開始使用RMS進行存儲讀取數據。新建RecordStore非常簡單,可以使用下面的靜態方法。
static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary)
注意recordStoreName應該是長度不超過32位的Unicode字符,大小寫敏感且在MIDlet套件裏面是唯一的,後面的boolean類型的createIfNecessary表示,如果標記爲true的時候,那麼RecordStore不存在就創建它。關閉RecordStore使用closeRecordStore()。在RMS中另外一個重要的概念就是Record,這就像數據庫中一行一行的數據一樣。下面我們首先對RecordStore中的方法進行區分,有些是用來獲得RecordStore信息的有些則是用來獲得Record信息的。
- 獲得RecordStore信息
int getVersion()
int getSize()
String getName()
long getLastModified() - 獲得Record信息
int getNumRecords()
int getNextRecordID()
int getRecordSize(int recordId)
下面講述如何對Record進行操作,主要包括添加、修改、讀取和刪除。
- 讀取記錄
byte[] getRecord(int recordId)
int getRecord(int recordId, byte[] buffer, int offset) - 添加記錄
int addRecord(byte[] data, int offset, int numBytes) - 更新記錄
setRecord(int recordId, byte[] newData, int offset, int numBytes) - 刪除記錄
deleteRecord(int recordId)
前面我們提到了ID和Index是不同的,因爲ID可能不連續,那麼我們如何來遍歷數據呢?很多人可能會想到使用for循環,但是由於id可能不連續,那麼這個結果是無法預測的。程序很可能會失敗。正是由於這樣的原因,在RMS中提供了一個重要的接口RecordEnumeration。它可以遍歷RecordStore中的數據。我們看看下面的方法。
RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)
在這個方法中還包括了RMS中的另外兩個接口RecordFilter和RecordComparator,他們是用來量身定製遍歷的結果集的,你可以實現RecordFilter來決定要把什麼樣的數據篩選出來,通過實現RecordComparator來決定數據的排序。最後的參數keepUpdated,如果設置爲true的話,那麼它會跟蹤RecordStore中的數據變化,並且會反映到我們列出的結果集中,要知道這是非常好費資源的操作,建議設置爲false。RecordEnumeration相當於一個雙向的數據鏈表。你可以通過調用nextRecordId()和previousRecordId()來不停的移動。關於RecordEnumeration的其他方法讀者可以參考java doc進行學習。
最後一點需要說明的就是共享機制,這是在MIDP2.0中提供的新特性。允許一個套件中的RecordStore被另外一個訪問,當然這是要在授權的模式下。首先我們看看原理圖
如果MIDlet suite1在創建RecordStore1的時候,授權模式爲AUTHMODE_ANY的話,那麼其他的套件就有可能訪問到RecordStore1,比如上圖中的MIDlet suite2。通常這樣的訪問通過兩個步驟來完成。
- 創建可以被共享的RecordStore
我們可以通過下面的方法來實現,必須要把authmode設置爲AUTHMODE_ANY。
static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode, boolean writable)
- 訪問RecordStore
如果另外一個MIDlet Suite中的MIDlet想訪問的話,那麼它需要知道要訪問的MIDlet suite的vendorName和suiteName,一般我們可以從jad文件中得到這兩個數據。我麼使用如下的方法,
static RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName)