关于j2me对txt文件操作基础操作

最近一直在搞PDA基于MTK平台开发,对于文本文件的操作是大伤脑筋,因为j2me不能针对文本文件写操作,所以引入jsr75,但是现有的功能操作也是过于简陋,对于操作几万条的数据无论是硬件还是软件都是一种挑战。

网上找了大量的资料,遇到同样问题的同行大有人在,要么是检索太慢,要么是文件太大读取时内存溢出。最后决定以分段方式对文件进行操作,将大文件分成多个小文件,每个文件存储数据500条。

第一个问题:

多文件操作首先要根据判断获取我们需要的文件,这里的解决办法是以每个文件最后一条数据卡号的十六进制作为文件名称进行存储。每个文件中的卡号是不连续的但是要保证是递增排序。

获取刷卡信息后读取卡号,利用二分法对文件进行检索,检索到我们需要的文件。

第二个问题:

起初文件的读写都是以UTF-8编码方式进行,每行数据64个字节,包括20位的档案ID,14位的卡号,20位的姓名,8位的金额。2位的回车空格。写入文件后在读取时每行的数据位数并不是原有的64位了,原因是在UTF-8编码的文件中汉字占到3-4个字节。这样我要修改第二十行的数据时候就不能使用64*19的方法利用fc.openOutputStream(bytesSize);进行追加。因为我不知道前19行有多少个汉字多出来多少个字节。导致追加位置不正确。

很遗憾的放弃了UTF-8这种编码方式,改用txt默认的编码方式,此时每行数据都为64位,我可以很轻松的利用64*n对第n+1行数据进行追加修改。

第三个问题:

读文件如果要获取第500行的数据,按照逐行读取的方式在现有的PDA上测试需要十几秒,这对PDA来说已经失去了意义,找了好多资料也没有什么好的解决方法,所以最终只能通过一个仅有的skip(bytesSize)来解决问题,查看API后发现,skip(bytesSize)方法其实也是对字节逐个读取。经过测试也的确如此,只是比自己逐行读取判断来的能快点。读取时采用了二分法,给每个文本文件的都设置了索引,将索引放在第一行,开始读取时读取第一行数据,利用二分法检索卡号所在的行数,然后计算出skip所要跳过的字节数,再通过读取文件的方式进行读取。

这是我对文本文件操作的基本思路,其中也存在很多问题,哪位仁兄有好的方法,希望能帮我想想。

/**
* 读取人员档案信息(worker.txt)
*
* @param filePath
* @throws IOException
* @throws IOException
*
*/
public String[] readWorker(String cardnum) throws IOException{

int bytesize=0;
String filename = this.findFile(cardnum);
String[] data = new String[6];
String[] data2 = new String[1];
if (filename.equals("0")) {// 没有卡号

data2[0]="卡号不存在!";
return data2;

} else if (filename.equals("1")) {//有何文件夹名字相同的文件但是没有文件夹

data2[0]="数据文件路径错误!";
return data2;

} else if (filename.equals("2")) {// 有文件夹没文件

data2[0]="没有数据文件!";
return data2;

}
String daId = "";
FileConnection fc = null;
FileConnection fcc =null;
InputStream readers=null;
InputStreamReader reader=null;
String index = null;
daId = "";

try {
fc = (FileConnection) Connector.open(filePath+"/"+filename+".txt");
readers = fc.openInputStream();
reader = new InputStreamReader(readers);
int firstLineFlag=0;
while((index = readLines(reader)) != null&& firstLineFlag<1){
bytesize=+index.getBytes().length+2;
firstLineFlag++;
int card=Integer.parseInt(cardnum);
String[] cards=this.splits(index, ",");
int iCount=0; //比较的次数
int iIndex=0;
int iStart=0;
int iEnd=cards.length;
while(true){
iCount++;
iIndex = (iStart+iEnd)/2;
if(Integer.parseInt(cards[iIndex])<card)
{
iStart = iIndex;
}
else if(Integer.parseInt(cards[iIndex])>card)
{
iEnd = iIndex;
}
else //获取到卡号所在行
{
String line="";//获取档案所在行字符串
fcc = (FileConnection) Connector.open(filePath+"/"+filename+".txt");
readers = fcc.openInputStream();
bytesize=bytesize+iIndex*64;
readers.skip(bytesize);//跳到所需行的首位
while ((line = readLine(readers)) != null) {
String num = this.format( line,20,14);// 获取txt文件中的卡号
daId = this.format( line, 0,20);// 获取档案ID
String name = this.format( line,34,20);// 获取txt文件中的姓名
String ye =this.format( line,54,8);// 获取txt文件中的余额

data[0] = daId;
data[1] = num;
data[2] = name;
data[3] = ye;
data[4]=bytesize+"";
data[5]=filename;

break;
}
readers.close();
fcc.close();

break;
}
}
System.out.println(iCount);
}
reader.close();
fc.close();

}
catch(Exception ex){


data2[0]="查询出现了异常"+ex.getMessage();
return data2;


}
finally{

fcc.close();
readers.close();
reader.close();
}

return data;
}

/**
* 获取档案信息
*
* @param reader
* @return
* @throws IOException
*/
private String readLine(InputStream reader) throws IOException {

byte[] bytes=new byte[64];
int readChar = reader.read(bytes, 0, bytes.length);

if (readChar==-1) {
return null;
}
System.out.println(new String(bytes));
return new String(bytes);
}

/**
*获取档案信息索引
*
* @param reader
* @return
* @throws IOException
*/
private String readLines(InputStreamReader reader) throws IOException {
int readChar = reader.read();

if (readChar == -1) {
return null;
}

StringBuffer string = new StringBuffer("");
while (readChar != -1 && readChar != '/n') {

if (readChar != '/r') {
string.append((char) readChar);
}
readChar = reader.read();
}
return string.toString();
}

/**
* 获取相应的文件
* @param cardNums
* @return
*/
public String findFile(String cardNums) {

int cardNum = Integer.parseInt(cardNums); // 当前卡号
FileConnection fc;
String cardNumStrArr[];
String fileNameStr = "";
int cardNumArr[];
try {
fc = (FileConnection) Connector.open(filePath);
if (!fc.exists()) {
fc.mkdir();// 文件夹不存在就创建
} else {
boolean isfolder = fc.isDirectory();
if (!isfolder) {
return "1"; // 判断不是文件夹则返回 没有文件夹
}
}
Enumeration enumeration = fc.list();
while (enumeration.hasMoreElements()) {
String fileNamei = (String) enumeration.nextElement();// 得到filePath下的所有文件名
fileNamei = fileNamei.substring(0, fileNamei.indexOf("."));
// 将文件名转换成10进制
int fileCardNum = Integer.valueOf(fileNamei, 16).intValue();
fileNameStr += fileCardNum + ",";
}
if (null != fileNameStr && !"".equals(fileNameStr)) {
fileNameStr = fileNameStr
.substring(0, fileNameStr.length() - 1);
cardNumStrArr = splits(fileNameStr, ",");
cardNumArr = new int[cardNumStrArr.length];
for (int i = 0; i < cardNumStrArr.length; i++) {
cardNumArr[i] = Integer.valueOf(cardNumStrArr[i])
.intValue();
}
for (int i = 0; i < cardNumArr.length; i++) {
for (int j = i + 1; j < cardNumArr.length; j++) {
if (cardNumArr[i] > cardNumArr[j]) {
int temp = cardNumArr[i];
cardNumArr[i] = cardNumArr[j];
cardNumArr[j] = temp;
}
}
}
if (null != cardNumArr && cardNumArr.length > 0) {
if (cardNumArr.length == 1) {
if (cardNum >= 1 && cardNum <= cardNumArr[0]) {// 第一个文件
fileName = Integer.toHexString(cardNumArr[0]);
} else {
fileName = "0";// 没有对应的文件
}
} else if (cardNumArr.length > 1) {
if (cardNum >= 1 && cardNum <= cardNumArr[0]) {// 第一个文件
fileName = Integer.toHexString(cardNumArr[0]);
} else if (cardNum > cardNumArr[cardNumArr.length - 1]) {// 找不到对应数据,卡号不存在
fileName = "0";
} else if (cardNum > cardNumArr[cardNumArr.length - 2]
&& cardNum <= cardNumArr[cardNumArr.length - 1]) { // 最后一个文件
fileName = Integer
.toHexString(cardNumArr[cardNumArr.length - 1]);
} else {// 除第一个和最后一个文件的其他文件
for (int i = 1; i < cardNumArr.length - 1; i++) {
if (cardNumArr[i] >= cardNum) {// 第一个大于等于考号的值
fileName = Integer
.toHexString(cardNumArr[i]);
break;
} else {
continue;
}
}
}
}
}
} else {
return "2";// 有文件夹没文件

}
} catch (IOException e) {
e.printStackTrace();
}

return fileName;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值