在J2ME中我们常常需要存储数据,J2ME存储数据的方式不同于web开发中用到数据库。J2ME给我们提供了Record Management System(RMS)及记录存储系统,它非常像web浏览器的Cookie,把数据写在本地的文件,但在MIDP中是没有文件概念的。
J2ME 记录管理系统 (RMS)提供了一种机制,通过这种机制,MIDlet 能够持久存储数据,并在以后检索数据。在面向记录的方法中,J2ME RMS 由多个 记录存储 构成。J2ME RMS 和 MIDlet 接口连接的概貌在图中给出。
每条记录都有一个ID,但是在向某个存储器中添加记录时ID是自动生成的。
对比一下数据库,我们可以这样理解RMS,RMS是本地化数据库,每个Record Store相当于数据库中的一个表,而每一条数据在添加到Record Store中时,默认的ID是自动增长的,这就像数据库表中的自增长主键列。巧合的是在不设置ID的种子和起始值时,RMS的ID和表的起始ID都为1。在一个以应用程序中所有的MIDlet共用这些Record Store,这些Record Store集合起来可以看做是一个数据库,只不过这个数据库能被这个应用程序的MIDlet所引用。
一般情况下我们对数据的操作无非就是增删查改,在J2ME中我们常常运用RMS来进行读写,下面是我写的一个简单的读写例子:
代码
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.org.sunny.rms; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import javax.microedition.rms.RecordEnumeration; import javax.microedition.rms.RecordStore; import javax.microedition.rms.RecordStoreException; import javax.microedition.rms.RecordStoreNotOpenException; /** * * @author Administrator */ public class RecordManager { RecordStore rms; public byte [] StringtoBytes(String str) { byte [] data = null ; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeUTF(str); data = baos.toByteArray(); baos.close(); dos.close(); } catch (Exception ex) { System.out.println( " 异常1 " ); ex.printStackTrace(); } return data; } public String BytesToString( byte [] data) { ByteArrayInputStream bais = new ByteArrayInputStream(data); DataInputStream dis = new DataInputStream(bais); String str = null ; try { str = dis.readUTF(); bais.close(); dis.close(); } catch (Exception ex) { System.out.println( " 异常2 " ); ex.printStackTrace(); } return str; } public String[] Read(String fileName){ String records[] = null ; try { rms = RecordStore.openRecordStore(fileName, true , RecordStore.AUTHMODE_ANY, true ); int NumberTotal = rms.getNumRecords(); records = new String[NumberTotal]; System.out.println(NumberTotal); for ( int i = 0 ;i < NumberTotal;i ++ ){ String temp = BytesToString(rms.getRecord(i + 1 )); records[i] = temp; } } catch (Exception ex) { System.out.println( " 异常3 " ); ex.printStackTrace(); } return records; } public String Save(String[] strs, String fileName) { String result = null ; try { rms = RecordStore.openRecordStore(fileName, true , RecordStore.AUTHMODE_ANY, true ); if (rms.getNumRecords() == 0 ) { for ( int i = 0 ; i < strs.length; i ++ ) { byte [] data = StringtoBytes(strs[i]); rms.addRecord(data, 0 , data.length); } } else { for ( int i = 0 ; i < strs.length; i ++ ) { byte [] data = StringtoBytes(strs[i]); rms.setRecord(i, data, 0 , data.length); } } System.out.println( " 保存时: " + rms.getNumRecords()); } catch (Exception ex) { System.out.println( " 异常4 " ); result = " 保存失败 " ; ex.printStackTrace(); } return result; }}
上面有4个方法,StringtoBytes是把字符串转换成字节数组,BytesToString是把字节数组转换成字符串,read和write分别是读和写的方法,RecordStore.openRecordStore()方法就是打开某个RecordStore(相当于打开某个表,然后对这个表进行查询或添加记录,修改等等)。
下面这个类是测试这个RMS类的读写,测试的效果如下:
代码
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ import com.org.sunny.rms.RecordManager; import com.sun.lwuit.Button; import com.sun.lwuit.Component; import com.sun.lwuit.Container; import com.sun.lwuit.Display; import com.sun.lwuit.Form; import com.sun.lwuit.Label; import com.sun.lwuit.TextField; import com.sun.lwuit.events.ActionEvent; import com.sun.lwuit.events.ActionListener; import com.sun.lwuit.geom.Dimension; import com.sun.lwuit.layouts.BorderLayout; import com.sun.lwuit.layouts.BoxLayout; import com.sun.lwuit.layouts.FlowLayout; import javax.microedition.midlet. * ; /** * @author Administrator */ public class RMSMidlet extends MIDlet { RecordManager rm = new RecordManager(); public void startApp() { Display.init( this ); Display.getInstance().callSerially( new Runnable() { public void run() { start(); } }); } public void start() { Form f = new Form( " RMS测试 " ); f.setLayout( new BoxLayout(BoxLayout.Y_AXIS)); final TextField txtName = new TextField(); final TextField txtAge = new TextField(); final TextField txtSex = new TextField(); final TextField txtCity = new TextField(); f.addComponent(createPair( " 姓名: " , txtName, 80 )); f.addComponent(createPair( " 年龄: " , txtAge, 80 )); f.addComponent(createPair( " 姓名: " , txtSex, 80 )); f.addComponent(createPair( " 年龄: " , txtCity, 80 )); Container btnContainer = new Container( new FlowLayout(Component.CENTER)); Button btnSave = new Button( " 保存信息 " ); btnContainer.addComponent(btnSave); f.addComponent(btnContainer); btnContainer = new Container( new FlowLayout(Component.CENTER)); Button btnRead = new Button( " 读取信息 " ); btnContainer.addComponent(btnRead); f.addComponent(btnContainer); btnSave.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { String[] strs = { txtName.getText(), txtAge.getText(), txtSex.getText(), txtCity.getText() }; // rm.Save(txtName.getText(), "Saleslion"); rm.Save(strs, " Saleslion " ); } }); btnRead.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { // txtAge.setText(rm.Read("Saleslion")); String[] strs = rm.Read( " Saleslion " ); System.out.println(strs.length); txtName.setText(strs[ 0 ]); txtAge.setText(strs[ 1 ]); txtSex.setText(strs[ 2 ]); txtCity.setText(strs[ 3 ]); } }); f.show(); } public Container createPair(String label, Component c, int minWidth) { Container pair = new Container( new BorderLayout()); Label l = new Label(label); Dimension d = l.getPreferredSize(); d.setWidth(Math.max(d.getWidth(), minWidth)); l.setPreferredSize(d); pair.addComponent(BorderLayout.WEST, l); pair.addComponent(BorderLayout.CENTER, c); return pair; } public void pauseApp() { } public void destroyApp( boolean unconditional) { }}