原则上来说,手机上尽量不允许大批量的操作RMS,但目前这个项目是一个阅读软件,不得不把下载到的书存到手机中,这就要反复操作RMS,项目期间出现过很多问题,现把几个主要的思想记录下来,以供在以后的项目中做为参考。
1.通过对已下载数据的RMS存储,可以实现文件的断点续传;
2.通过对下载列表的记录,可以实现已下载、正在下载、暂停,等待下载等的区分;
3.因为是反复操作RMS,所以对内存的回收一定要注意,操作结束立刻要回收;
4.因为是反复操作RMS,所以每次有设计到RMS有关的操作,必然遍历已下载或比较书名等,都要先读取下RMS;
5.Symbian S40系统的RMS非常有限,大致为1-2百k,不适合大数据存储,S60理论上没有限制,但存到20M时,有的机子会出问题;
6.本代码范例为以对象的方式反复操作RMS,如果小范围内使用RMS,如只记录下用户名密码等,是不需要这么负责的代码的;
代码范例:
package com.xuudoo.booking;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.rms.RecordStore;
import com.xuudoo.ewl.EWLScreen;
public final class RMSRecorderIfno {
private ByteArrayOutputStream dis;
private ByteArrayInputStream is;
private DataOutputStream dis1;
private DataInputStream is1;
public RecordStore rs;
private String rmsName;
public boolean boon;
private static long length;
private static boolean istrue = false;
/** *//**
* RMS命名规则:
* RecordStore.openRecordStore(storeName, false);
*
* @param storeName= "002_" + bookName + "_packet";//
* @param storeName= "002_" + bookName + "_mgz"; //存储书
* @param storeName= "002_" + bookName + "_info"; //
* @param storeName= "002_" + bookName + "_file"; //
* @param storeName= "002_" + bookName + "_byte"; //存储每块数据中的废字节数
* @param storeName= "002_" + bookName + "_url"; //存储url和一本书的总数据块数
* @param storeName= "002_" + "downloaded"; //存储已经下载结束书的ID
* @param storeName= "002_" + "downloadpause"; //存储暂停下载书的ID
*/
public RMSRecorderIfno() {
if (!istrue) {
istrue = true;
length = getAvailable();
}
}
/** *//**
* 打开一个仓储
* @param name:仓储名字
* @param flag:值为true,当不存在时创建一个新的store
* @return
*/
public final boolean open(String name, boolean flag) {
try {
rmsName = name;
rs = RecordStore.openRecordStore(rmsName, flag);
rs.setMode(0, true);
boon = true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public final void openWriteStream() {
dis = new ByteArrayOutputStream();
dis1 = new DataOutputStream(dis);
}
public final void closeWriteStream() {
try {
if (dis1 != null){
dis1.close();
dis1 = null;
}
if (dis != null) {
dis.close();
dis = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public final void write(int k) {
try {
dis1.writeInt(k);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final void write(byte data[]) {
try {
dis1.write(data);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final void write(boolean flag) {
try {
dis1.writeBoolean(flag);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final void write(String s) {
try {
dis1.writeUTF(s);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final void write(short word0) {
try {
dis1.writeShort(word0);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final byte[] saveStreamToByteArray() {
try {
dis1.flush();
} catch (Exception exception) {
exception.printStackTrace();
}
return dis.toByteArray();
}
/** *//**
* 读取位置K的数据
* @param k
* @return
*/
public final boolean openReadStream(int k) {
try {
is = new ByteArrayInputStream(getRecord(k));
is1 = new DataInputStream(is);
} catch (Exception _ex) {
if(BookingMidlet.DEBUG)
_ex.printStackTrace();
return false;
}
return true;
}
/** *//**
* 读取整数值
* @return
*/
public final int readInt() {
try {
return is1.readInt();
} catch (Exception exception) {
if(BookingMidlet.DEBUG)
exception.printStackTrace();
return 0;
}
}
public final boolean readBoolean() {
try {
return is1.readBoolean();
} catch (Exception exception) {
exception.printStackTrace();
return false;
}
}
public final String readString() {
try {
return is1.readUTF();
} catch (Exception exception) {
return null;
}
}
/** *//**
* 返回数据库中的记录条数
* @return
*/
public final int size() {
try {
return rs.getNumRecords();
} catch (Exception e) {
if(BookingMidlet.DEBUG){
e.printStackTrace();
}
return -1;
}
}
public final void setRecord(int k, byte abyte[]) {
try {
rs.setRecord(k, abyte, 0, abyte.length);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public final int addRecord(byte abyte0[]) {
try {
return rs.addRecord(abyte0, 0, abyte0.length);
} catch (Exception e) {
if(rs != null){
UIManager.showAlert("下载失败,储存器已满,请及时清理");
}
if(UIManager._instance.downloadtool != null && UIManager._instance.downloadtool.conn != null){
UIManager._instance.downloadtool.CloseMidlet();
UIManager._instance.removeDownloadingItem(UIManager._instance.downloadtool.item);
UIManager._instance.removeDownloadedItem(UIManager._instance.downloadtool.item);
delete("002_" + UIManager._instance.downloadtool.imageName + "_byte");
delete("002_" + UIManager._instance.downloadtool.imageName + "_url");
if(UIManager._instance.downloadtool.rms != null){
UIManager._instance.downloadtool.rms.close();
UIManager._instance.downloadtool.rms = null;
}
delete("002_" + UIManager._instance.downloadtool.imageName + "_mgz");
if(BookingMidlet.DEBUG)
EWLScreen.prompt2 = "出错了,请注意!!";
}
return -1;
}
}
/** *//**
* 读取位置K上的字节数组数据
* @param k
* @return
*/
public final byte[] getRecord(int k) {
try {
return rs.getRecord(k);
} catch (Exception exception) {
exception.printStackTrace();
exception.printStackTrace();
return null;
}
}
public final void close() {
try {
if (dis1 != null) {
dis1.close();
dis1 = null;
}
if (dis != null) {
dis.close();
dis = null;
}
if (is1 != null) {
is1.close();
is1 = null;
}
if (is != null) {
is.close();
is = null;
}
if (rs != null) {
boon = false;
rs.closeRecordStore();
rs = null;
return;
}
} catch (Exception _ex) {
_ex.printStackTrace();
}
}
public static final void delete(String s) {
try {
RecordStore.deleteRecordStore(s);
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static final boolean a(long l) {
if (l > 0L && l < length) {
length -= l;
return true;
} else {
return false;
}
}
public static final boolean b(long l) {
if (l > 0L && length + l <= getAvailable()) {
length += l;
return true;
} else {
return false;
}
}
public static final long h() {
return length;
}
public static final long getAvailable() {
long l;
RecordStore recordstore;
try {
l = (recordstore = RecordStore.openRecordStore("freeMemory", true)).getSizeAvailable();
recordstore.closeRecordStore();
return l;
} catch (Exception exception) {
exception.printStackTrace();
return 0L;
}
}
public static final String[] getList() {
try {
return RecordStore.listRecordStores();
} catch (Exception exception) {
exception.printStackTrace();
return null;
}
}
public static final boolean exists(String name) {
String rmslistname[] = getList();
try {
// rs = RecordStore.openRecordStore(name, false);
} catch (Exception e) {
e.printStackTrace();
}
if (rmslistname == null)
return false;
for (int k = 0; k < rmslistname.length; k++)
if (rmslistname[k].equals(name))
return true;
return false;
}
public static final synchronized void a(String s, int k) {
// Object obj1 = null;
try {
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
DataOutputStream obj = new DataOutputStream(bytearrayoutputstream);
obj.writeInt(k);
a(s, bytearrayoutputstream.toByteArray());
if (obj != null)
((DataOutputStream) (obj)).close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static final synchronized void a(String s, byte abyte0[]) {
Object obj = null;
try {
if (((RecordStore) (obj = RecordStore.openRecordStore(s, true))).getNumRecords() == 0)
((RecordStore) (obj)).addRecord(abyte0, 0, abyte0.length);
((RecordStore) (obj)).setRecord(1, abyte0, 0, abyte0.length);
if (obj != null)
((RecordStore) (obj)).closeRecordStore();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
public static final synchronized boolean d(String s) {
String as[];
if ((as = RecordStore.listRecordStores()) == null)
return false;
for (int k = 0; k < as.length; k++)
if (as[k].equals(s))
return true;
return false;
}
public static final synchronized int e(String s) {
System.out.println("bn.e(string) s=" + s);
Object obj;
obj = null;
// Object obj1 = null;
int k;
try {
obj = new ByteArrayInputStream(f(s));
DataInputStream datainputstream;
datainputstream = new DataInputStream((InputStream) (obj));
k = datainputstream.readInt();
((ByteArrayInputStream) (obj)).close();
return k;
} catch (Exception exception) {
try {
if (obj != null)
((ByteArrayInputStream) (obj)).close();
} catch (Exception ex) {
ex.printStackTrace();
}
exception.printStackTrace();
return 0;
}
}
public static final synchronized byte[] f(String s) {
System.out.println("bn.f(string) s=" + s);
byte abyte0[] = (byte[]) null;
try {
RecordStore obj = RecordStore.openRecordStore(s, true);
if (obj.getNumRecords() == 1)
abyte0 = ((RecordStore) (obj)).getRecord(1);
if (obj != null)
obj.closeRecordStore();
return abyte0;
} catch (Exception exception) {
exception.printStackTrace();
return null;
}
}
}