基于J2ME持久存储技术的研究

时间:2022-09-14 06:55:06

基于J2ME持久存储技术的研究

摘要:随着移动设备性能的不断提高,人们对手机等移动通信终端的应用需求越来越迫切,基于此平台的应用系统将越来越丰富。该文探讨了运用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 = null; //定义输入流对象

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 = null;

}

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 = null; // 返回的结果字符串数组

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 = null;

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.

上一篇:轻量级Web表单数据封装框架实现 下一篇:《计算机组装与维护》课程教学改革探讨