摘要:隨著移動設備性能的不斷提高,人們對手機等移動通信終端的應用需求越來越迫切,基于此平臺的應用系統將越來越豐富。該文探討了運用J2ME技術中的記錄管理系統(Record Management System,RMS)實現數據的持久存儲。通過對RMS的應用和文件流的操作提出了基于移動通信終端的公交查詢系統的解決方案。
關鍵詞:J2ME;RMS;持久存儲;文件流;公交查詢
中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2009)04-0880-03
The Research of Persistent Storage Technology Based on J2ME
YAO Qing1, RAO Li-jun2, WANG Yan-yang2
(Xi’an University of Architecture and Technology,Xi’an 710055,China)
Abstract: With the improvement in the performance of mobile devices, people to the mobile device application demands are more and more urgent, the application system base on this platform will be more and more abundant. This article discussed that the application of Record Management System (RMS) in the J2ME technology implemented the data persistent storage. Through the application of RMS and the operation of file stream, we proposed the solution of bus information query base on the mobile device.
Key words: J2ME; RMS; persistent storage technology; file Stream; bus information query
1 引言
隨著3G時代的到來,移動電話正在成為不可或缺的個人工具,成為移動信息時代管理個人商務、工作和生活的工具。而與其相關的軟件市場更是具有無窮潛力,目前,人們對計算機功能的依賴越來越強烈,移動手機終端的作用也將會體現出越來越重要的位置。人們希望手機像個人計算機一樣,能方便地為這些移動設備安裝各種需要的應用軟件,而不用重新購買新的設備。面對上述的各種需求,基于手機的移動應用開發逐漸成為一個炙手可熱的話題。
基于Java2平臺微型版(Java2 Platform Micor Edition,J2ME)的通用解決方案提高了手機軟件的附加值,越來越多的手機廠商都支持了Java軟件的應用,基于J2ME平臺的手機應用也將成為今后手機軟件發展的趨勢。
數據持久存儲是一個應用程序最基本的問題,任何應用系統必須要解決這一問題。數據持久必須以某種方式保存,不能丟失,并且能夠有效的、簡便的檢索及更新。記錄管理系統(Record Management System,RMS),它的出現為在移動信息設備上進行數據的持久存儲提供了支持,實現了數據的存儲和檢索功能,完成了基本的數據管理。它實現的功能相當于一個小型的手機信息數據庫。但是,考慮手機平臺的現實特點,內存的使用具有很大的限制,在手機程序中如何實現數據的持久性存儲具有現實的意義,本文討論了一種運行于移動手持設備的公交查詢系統的實現方案,通過這個案例能對記錄管理系統的應用有一個更深層的認識,介紹了記錄管理系統的設計思想、使用方法及技巧[1]。
2 RMS體系結構
RMS(Record Management System)是一個簡單的面向記錄(Record)的數據庫,也稱為記錄存儲(RecordStore)。在J2ME中,RMS作為唯一的永久性存儲工具,可以把它看作是由許多記錄組合而成的一個個數據庫表文件,這些記錄將持久地保存和支持跨多個MIDlet的請求。MIDlet的記錄存儲由平臺負責維護,也由平臺決定生成的位置,但決定記錄存儲命名空間的是MIDlet套件(即打包在一起的一個或多個MIDlet)。
在RMS中存儲的數據是以記錄(Record)為單位的,記錄不能單獨存在,必須屬于某個RecordStore。RMS記錄存儲中的每一條記錄都包括兩列:一列用于存儲惟一的記錄標識,另外一列存儲代表記錄中數據的一組字節。表1展示了一個簡單的記錄存儲數據庫。
表1 一個簡單的記錄數據庫
■
記錄管理系統沒有對數據的形式做限制,記錄可以是字符、數字、數組或者圖片,只要數據可以被轉化成字節數組就可以。惟一記錄ID是一個整型值,用作記錄的主關鍵字。第一條記錄ID為1,然后是2,以此類推。一條記錄被刪除之后,它的記錄ID不會被重用。也就是說,如果表中有三條記錄,ID分別是1,2 和3,刪除ID 2,將把這個標識永久性地從記錄存儲中刪除。如果我們向這個表中添加另外一條記錄,那么該行的標識將會是4。并且所添加的每個記錄的長度不一定相同。應用程序負責對數據進行編碼,將其轉換位字節數組并寫入到RMS中;從RMS中讀出的數據依然是字節數組,應用程序需要對數據進行解碼并轉換為原始數據。
記錄存儲是用名稱來標識的。記錄存儲的名稱最多可以包含32個字符,并且所有字符都是大小寫敏感的。同一個MIDlet套件中不會包含兩個名稱相同的記錄存儲。每個記錄存儲都會有個全名,即“MIDlet Suite名稱+供貨商名稱+記錄倉庫的名稱”。
3 實現公交查詢中的關鍵技術
本文通過實現公交查詢系統為例,詳細說明了RMS數據庫在J2ME技術中的應用,下面就結合代碼介紹一下記錄管理系統的設計思想、使用方法及技巧。
3.1 數據的讀入
由于手機資源受限,數據的大小受到了內存的限制,而完成信息查詢系統有需要大量的數據,所以首要問題是應當怎樣把數據按照規定格式放入RMS中去。顯然,由于數據量比較大,不能選擇直接用程序寫入,從文本文件中讀取數據是比較合理的選擇。在這里我們要把所有的公交信息寫入一個UTF-8字符編碼txt文件,然后通過對文件流的操作把它讀入RMS中。定義一條標準的公交信息為:
{車次, 起始時間, 結束時間, 始發站, 終點站, 上行路線, 下行路線, 票價}
公交信息的數據分類都由“,”隔開,下文是數據格式化的程序的部分核心代碼,代碼力求短小精煉,并輔助適當的說明和注釋。
從txt讀出數據串源程序,這里的參數name為txt資源地址:
public String read_UTF(String name){
String strReturn = \"\"; //數據字符串定義
InputStream in = 1; //定義輸入流對象
byte[] data = new byte[1024];//定義數據大小
try {
in = getClass().getResourceAsStream(name); //查找資源文件
in.read(data); //讀入數據
in.close();
strReturn = new String(data,\"UTF-8\");
} catch (Exception e) {
System.out.println(\"read error\" + e.toString());
}
finally{
in = 1;
}
return strReturn; //返回數據字符串
}
在這里還要用到字符串處理的一點技巧,雖然Java中提供的String類的字符串方法很多,但是由于J2ME只包含一部分方法。這里需要用到String類中的slipt()方法,但是J2ME里面卻沒有包含這個方法,所以這里重新寫了分隔方法,下面是源代碼:
public static String[] split(String original,String regex){
//參數original為需要分隔字符串,regex為分割字符
int startIndex = 0;//取子串的起始位置
Vector v = new Vector(); //將結果數據先放入Vector中
String[] str = 1; //返回的結果字符串數組
int index = 0; //存儲取子串時起始位置
startIndex = original.indexOf(regex); //獲得匹配子串的位置
while(startIndex < original.length() startIndex != -1)
{
String temp = original.substring(index,startIndex);
System.out.println(\" \" + startIndex);
v.addElement(temp); //取子串
index = startIndex + regex.length();//設置取子串的起始位置
startIndex = original.indexOf(regex,startIndex + regex.length()); //獲得匹配子串的位置
}
v.addElement(original.substring(index + 1 - regex.length()));//取結束的子串
str = new String[v.size()];//將Vector對象轉換成數組
for(int i=0;i { str[i] = (String)v.elementAt(i); } return str; //返回生成的數組 } 3.2 公交數據的讀取寫入 公交數據安全完整的讀出寫入是整個系統的關鍵,這里建立了一個公交信息類BusDataEntity,它抽象地代表了RMS中的一條記錄,RMS里只能存儲字節化后的數據,所以在這個類里面必須定義它自身的讀取寫入RMS的方法,寫入方法encode()通過把整個對象序列化成byte數組存入RMS記錄倉儲,讀取方法decode()從RMS數據倉儲中讀出一個byte數組,然后恢復成原本的對象內部的狀態,在此我們要借助四個類的協助,它們分別是ByteArrayOutStream、ByteArrayInStream、DataOutputStream和DataInputStream。下面就是這兩個方法的源代碼: public byte[] encode(){ byte[] result = 1; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); dos.writeUTF(busID);//寫入車次 ... //寫入其它信息 result = bos.toByteArray();//將數據全部轉化為byte[] dos.close(); bos.close(); } catch (Exception e) {} return result; } public void decode(byte[] data){ try { ByteArrayInputStream bis = new ByteArrayInputStream(data); DataInputStream dis = new DataInputStream(bis); busID = dis.readUTF();//解析出車次 ... //解析其它信息 dis.close(); bis.close(); } catch (Exception e) {} } 這里用DataOutputStream,將數據先進行格式的轉換和數據編碼,然后再存入byte 數組中,完成了存的過程。取的過程與此類似,不同的是輸出流變成了輸入流,編碼過程變成解碼過程。 3.3 RMS中數據的操作 由于RMS數據表結構比較簡單,所以對其數據的操作非常簡單,J2ME中提供了對數據操作的很多方法,包括了增、刪、改、查。當要訪問RMS數據時,必須通過RecordStore類提供的openRecordStore()方法開啟RMS。開啟RMS之后,當我們要寫入一條公交信息時,只需用addRecord((BusDataEntity). Encode(),0,(BusDataEntity). Encode().length)即可把數據添加到RMS中。其它的操作這里不做詳細介紹。 當涉及多條記錄的操作,如記錄存儲中記錄的遍歷、排序和查找,就要使用枚舉器、比較器和過濾器。構建枚舉器、比較器和過濾器對象需要實現RMS 類包中的其它三個接口,分別為枚舉器接口RecordEnumeration、比較器接口RecordComparator 和過濾器接口RecordFilter。 4 結束語 根據官方公布的統計數據,我國移動電話用戶已突破6億,因此在可預見的將來,移動手持設備的應用將帶來比傳統通信業務以及短信息業務更高的利潤,本文討論的這種基于J2ME的公交查詢系統是對這種應用的一個探討,為開發更復雜的應用系統打下基礎,本程序設計實現了手機上以J2ME為平臺的公交查詢的開發,采用從外部文件讀取數據,具有一定的可移植性,下一步要研究基于這個方向的免費無線應用服務,這樣能夠為用戶帶來更為方便實用的體驗。 參考文獻: [1] 詹建飛.java ME核心技術與最佳實踐[M].北京:電子工業出版社,2007. [2] 王森.java手機/PDA程序設計入門[M].北京:電子工業出版社,2004. [3] Keogh J.J2ME 開發大全[M].北京:清華大學出版社,2004. [4] 詹建飛.J2ME開發精解[M].北京:電子工業出版社,2006. [5] 仵博,張立涓,池瑞楠.J2ME無線開發實用教程[M].北京:清華大學出版社,2006.