RMS概念解析與使用指南

RMS(Record Management System)是MIDP中一個非常重要的子系統,因爲它是J2ME應用程序進行持久性存儲的唯一途徑。當然你的系統如果支持JSR75的話,那麼你可以使用FileConnection來對文件進行操作,那超出了本文的討論範圍。持久性存儲在我們編寫應用程序的時候經常要用到,比如紀錄遊戲的排行榜、記錄用戶輸入的用戶名和密碼等。本文將主要從RMS的基本概念和使用指南方面進行介紹,目的在於給讀者進行一定的指導。



    RMS是首先在MIDP1.0中提出的,它所在的包是javax.microedition.rms,在這個包裏面總共包括四個接口、一個類和五個異常。由此可見RMS設計的非常小巧,這正是爲了滿足移動信息設備資源受限的需求。下面我們先弄清楚幾個概念。
  1. 什麼是持久性存儲?
    持久性存儲簡單的理解就是數據不因爲程序的退出而丟失,一般我們在程序中聲明的變量都是存儲在stack或者heap上的,程序退出後這些數據會被清除以釋放資源。而存儲在RMS中的數據是不會被清除的。
  2. RMS的數據存儲在哪裏?
    MIDP規範中沒有規定RMS的數據必須存儲在哪裏,而是由廠商來具體實現。一般存儲在非揮發性的內存空間。因此這是對程序員透明的。
  3. RMS的容量最小爲多少?
    MIDP中規定廠商實現RMS的時候,提供的存儲空間不能小於8KB,例如筆者的Nokia 6108的RMS空間爲30KB。
  4. RMS中按照Record來存儲的,ID是不是等於索引?
    ID和索引的區別還是很大的,ID從1開始計數,這和數組的0開始計數有一些不同。ID可以是不連續的,當一個ID標記的Record被刪除後那麼對應的ID也就變得無效了。ID是不能重複使用的。
  5. RMS對存儲在其中的數據格式有具體要求嗎?
    答案是沒有,只要數據可以被轉換成byte[]那麼這個數據就可以存儲在RMS中,取出的時候仍然是byte[]。因此這就要求我們開發人員來描繪數據的樣子,因爲RMS只是負責把數據按照byte[]寫入和讀出。
  6. 在一個MIDlet套件中,RecordStore可以被共享嗎?
    可以
  7. 一個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信息的。

  1. 獲得RecordStore信息
    int getVersion()
    int getSize()
    String getName()
    long getLastModified()
  2. 獲得Record信息
    int getNumRecords()
    int getNextRecordID()
    int getRecordSize(int recordId)

下面講述如何對Record進行操作,主要包括添加、修改、讀取和刪除。

  1. 讀取記錄
    byte[] getRecord(int recordId)
    int getRecord(int recordId, byte[] buffer, int offset)
  2. 添加記錄
    int addRecord(byte[] data, int offset, int numBytes)
  3. 更新記錄
    setRecord(int recordId, byte[] newData, int offset, int numBytes)
  4. 刪除記錄
    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被另外一個訪問,當然這是要在授權的模式下。首先我們看看原理圖
2005129104723983.gif 

 

 

 

 

 

 

 

 

 

如果MIDlet suite1在創建RecordStore1的時候,授權模式爲AUTHMODE_ANY的話,那麼其他的套件就有可能訪問到RecordStore1,比如上圖中的MIDlet suite2。通常這樣的訪問通過兩個步驟來完成。

  1. 創建可以被共享的RecordStore
    我們可以通過下面的方法來實現,必須要把authmode設置爲AUTHMODE_ANY
    static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode, boolean writable)
      
  2. 訪問RecordStore
    如果另外一個MIDlet Suite中的MIDlet想訪問的話,那麼它需要知道要訪問的MIDlet suite的vendorName和suiteName,一般我們可以從jad文件中得到這兩個數據。我麼使用如下的方法,
    static RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName) 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章