
RMS(Record Management System)是MIDP中一個非常重要的子系統(tǒng),因?yàn)樗荍2ME應(yīng)用程序進(jìn)行持久性存儲的唯一途徑。當(dāng)然你的系統(tǒng)如果支持JSR75的話,那么你可以使用FileConnection來對文件進(jìn)行操作,那超出了本文的討論范圍。持久性存儲在我們編寫應(yīng)用程序的時候經(jīng)常要用到,比如紀(jì)錄游戲的排行榜、記錄用戶輸入的用戶名和密碼等。本文將主要從RMS的基本概念和使用指南方面進(jìn)行介紹,目的在于給讀者進(jìn)行一定的指導(dǎo)。
RMS是首先在MIDP1.0中提出的,它所在的包是javax.microedition.rms,在這個包里面總共包括四個接口、一個類和五個異常。由此可見RMS設(shè)計(jì)的非常小巧,這正是為了滿足移動信息設(shè)備資源受限的需求。下面我們先弄清楚幾個概念。- 什么是持久性存儲?
持久性存儲簡單的理解就是數(shù)據(jù)不因?yàn)槌绦虻耐顺龆鴣G失,一般我們在程序中聲明的變量都是存儲在stack或者h(yuǎn)eap上的,程序退出后這些數(shù)據(jù)會被清除以釋放資源。而存儲在RMS中的數(shù)據(jù)是不會被清除的。 - RMS的數(shù)據(jù)存儲在哪里?
MIDP規(guī)范中沒有規(guī)定RMS的數(shù)據(jù)必須存儲在哪里,而是由廠商來具體實(shí)現(xiàn)。一般存儲在非揮發(fā)性的內(nèi)存空間。因此這是對程序員透明的。 - RMS的容量最小為多少?
MIDP中規(guī)定廠商實(shí)現(xiàn)RMS的時候,提供的存儲空間不能小于8KB,例如筆者的Nokia 6108的RMS空間為30KB。 - RMS中按照Record來存儲的,ID是不是等于索引?
ID和索引的區(qū)別還是很大的,ID從1開始計(jì)數(shù),這和數(shù)組的0開始計(jì)數(shù)有一些不同。ID可以是不連續(xù)的,當(dāng)一個ID標(biāo)記的Record被刪除后那么對應(yīng)的ID也就變得無效了。ID是不能重復(fù)使用的。 - RMS對存儲在其中的數(shù)據(jù)格式有具體要求嗎?
答案是沒有,只要數(shù)據(jù)可以被轉(zhuǎn)換成byte[]那么這個數(shù)據(jù)就可以存儲在RMS中,取出的時候仍然是byte[]。因此這就要求我們開發(fā)人員來描繪數(shù)據(jù)的樣子,因?yàn)镽MS只是負(fù)責(zé)把數(shù)據(jù)按照byte[]寫入和讀出。 - 在一個MIDlet套件中,RecordStore可以被共享嗎?
可以 - 一個MIDlet套件中的RecordStore可以被另外一個RecordStore訪問嗎?
在MIDP1.0中不可以,在MIDP2.0中推出了共享機(jī)制,通過共享可以實(shí)現(xiàn)。
上面以7個問題的形勢總結(jié)了RMS中需要注意的基本概念,下面我們看看如何使用RMS。一般初學(xué)者學(xué)習(xí)RMS的時候通常會被他們的方法給弄的不知如何下手,因?yàn)楹芏喾椒瓷先ズ茴愃啤_@里我進(jìn)行如下的總結(jié),提供一些使用指南給大家。
首先讀者應(yīng)該清楚RecordStore就相當(dāng)于一個數(shù)據(jù)庫,你必須新建一個這樣的數(shù)據(jù)庫才可以開始使用RMS進(jìn)行存儲讀取數(shù)據(jù)。新建RecordStore非常簡單,可以使用下面的靜態(tài)方法。
static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary)
注意recordStoreName應(yīng)該是長度不超過32位的Unicode字符,大小寫敏感且在MIDlet套件里面是唯一的,后面的boolean類型的createIfNecessary表示,如果標(biāo)記為true的時候,那么RecordStore不存在就創(chuàng)建它。關(guān)閉RecordStore使用closeRecordStore()。在RMS中另外一個重要的概念就是Record,這就像數(shù)據(jù)庫中一行一行的數(shù)據(jù)一樣。下面我們首先對RecordStore中的方法進(jìn)行區(qū)分,有些是用來獲得RecordStore信息的有些則是用來獲得Record信息的。
- 獲得RecordStore信息
int getVersion()
int getSize()
String getName()
long getLastModified()
- 獲得Record信息
int getNumRecords()
int getNextRecordID()
int getRecordSize(int recordId)
下面講述如何對Record進(jìn)行操作,主要包括添加、修改、讀取和刪除。
- 讀取記錄
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是不同的,因?yàn)镮D可能不連續(xù),那么我們?nèi)绾蝸肀闅v數(shù)據(jù)呢?很多人可能會想到使用for循環(huán),但是由于id可能不連續(xù),那么這個結(jié)果是無法預(yù)測的。程序很可能會失敗。正是由于這樣的原因,在RMS中提供了一個重要的接口RecordEnumeration。它可以遍歷RecordStore中的數(shù)據(jù)。我們看看下面的方法。
RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)
在這個方法中還包括了RMS中的另外兩個接口RecordFilter和RecordComparator,他們是用來量身定制遍歷的結(jié)果集的,你可以實(shí)現(xiàn)RecordFilter來決定要把什么樣的數(shù)據(jù)篩選出來,通過實(shí)現(xiàn)RecordComparator來決定數(shù)據(jù)的排序。最后的參數(shù)keepUpdated,如果設(shè)置為true的話,那么它會跟蹤RecordStore中的數(shù)據(jù)變化,并且會反映到我們列出的結(jié)果集中,要知道這是非常好費(fèi)資源的操作,建議設(shè)置為false。RecordEnumeration相當(dāng)于一個雙向的數(shù)據(jù)鏈表。你可以通過調(diào)用nextRecordId()和PReviousRecordId()來不停的移動。關(guān)于RecordEnumeration的其他方法讀者可以參考java doc進(jìn)行學(xué)習(xí)。
最后一點(diǎn)需要說明的就是共享機(jī)制,這是在MIDP2.0中提供的新特性。允許一個套件中的RecordStore被另外一個訪問,當(dāng)然這是要在授權(quán)的模式下。首先我們看看原理圖
如果MIDlet suite1在創(chuàng)建RecordStore1的時候,授權(quán)模式為AUTHMODE_ANY的話,那么其他的套件就有可能訪問到RecordStore1,比如上圖中的MIDlet suite2。通常這樣的訪問通過兩個步驟來完成。
- 創(chuàng)建可以被共享的RecordStore
我們可以通過下面的方法來實(shí)現(xiàn),必須要把a(bǔ)uthmode設(shè)置為AUTHMODE_ANY。
static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode, boolean writable)
- 訪問RecordStore
如果另外一個MIDlet Suite中的MIDlet想訪問的話,那么它需要知道要訪問的MIDlet suite的vendorName和suiteName,一般我們可以從jad文件中得到這兩個數(shù)據(jù)。我么使用如下的方法,
static RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName)
本文的主要目的是介紹RMS的基本概念以及為讀者提供如何使用RMS中的方法提供一些指導(dǎo)。想進(jìn)一步研究RMS,讀者可以參考源碼下載專區(qū)筆者提供的一個基于midp1.0實(shí)現(xiàn)的手機(jī)通信錄。
(出處:http://www.survivalescaperooms.com)