对文本文件的存取
要看书得有书才行,不可能把书本认为分段以String的形式体现,那样也太……了,呵呵。随便选了文章用UltraEdit把它存储为unicode编码格式,因为me印象中java是直接支持unicode的。
印象中MIDP中好像有存取资源的函数,既然可以
Image img = Image.createImage(imgpath);
Image类中对createImage的声明:public static Image createImage(String name) throws IOException
那想来文本等资源也是可以通过类似的方法存取的。在docs中找了找,果不其然,系统支持对资源的存取,并且自动生成了InputStream,具体声明如下:
类Class中
public InputStream getResourceAsStream(String name)
Finds a resource with a given name. This method returns null if no resource with this name is found. The rules for searching resources associated with a given class are profile specific.
如果文件不存在,返回null;如果存在,就打开为InputStream。寻找资源的规则是在profile中有定义的,具体me就管不了那么多了。
既然生成的是InputStream,那可得详细看看java.io包是怎么回事。InputStream是以byte为单位进行读取处理的,这效率可真有点低。DataInputStream可以读取指定的类型,如char、int等,还能对特定的编码解码,如utf,另外readChar读出的字符默认是unicode。java真是个基于unicode的语言,爽。做了个测试用的MIDlet,嘿嘿,不成,读出的都是乱码。问题出在哪里了呢?!再次查看docs,没错,DataInputStream实现了DataInput接口,其中readChar是读取的unicode字符。
在接口DataInput中对readChar的定义:
public char readChar() throws IOExceptionReads
an input char and returns the char value. A Unicode char is made up of two bytes. Let a be the first byte read and b be the second byte. The value returned is: (char)((a << 8) | (b & 0xff))
This method is suitable for reading bytes written by the writeChar method of interface DataOutput.
Returns:the Unicode char read.
不死心,再试,仍然不行!闷……是不是me对接口以及抽象类的掌握还不够?莫不成还要me继承一个DataInputStream手动对readChar进行实现?不管那么多,试试再说,毕竟项目还得继续下去
构造了一个DataInputStream对象,一个个读取byte,然后按照上面的规则手动对连续读取的两个字节进行处理。测试,输出正确的中文字符。怪事,不过不管怎么怪,先放放再说。
???测试继续中,发现了一个问题,以unicode格式存储的文件,前两个byte为FF FE(十六进制),又用UE存了几个文件测试,只要是unicode编码方式存储,头两个字节都是FF FE。不知道是不是unicode编码文本文件的识别文件头?!
手动测试DataInputStream支不支持mark和rewind。一运行就出错,说明j2me中对资源文件存取生成的InputStream不支持mark,当然reset也不支持了。幸亏支持skipBytes,呵呵,要不麻烦真大了。因为必须实现对该文件的向前向后读取,这时候需要移动文件指针。不支持reset、rewind功能带来了一些障碍,me后来通过其他方法实现了这些功能。具体来讲就是定义一个FileLib类,其中实现了类似windows系统中对file文件读取的功能,如读取字节、reset、close,关键在于根据构建器参数(文件名)构造InputStream,在获取文件大小的函数中,先记录当前位置,关闭InputStream,重新打开(此时文件指针在文件头部),遍历到文件尾部(read的结果为负1),关闭,然后再打开,skip到原来的位置。很是麻烦,但功能毕竟实现了。
示例代码如下:
/*
* FileLib.java
*
* Created on 2004年10月7日, 下午1:21
*/
package heart5.lib;
import java.io.DataInputStream;
import java.io.InputStream;
/**
* FileLib,对文件进行操作的库;此处文件指资源包中以文件形式存在的资源
* 是否存在,大小
* @author heart5
* @version start
*/
public class FileLib {
/**
* InputStream,通过getResource获取输入流
*/
InputStream is;
/**
* DataInputStream,数据输入流,支持readByte等功能
* 实现了DataInput接口
*/
DataInputStream dis;
/**
* 数据输入流的指针
*/
public int disIdx = 0;
/**
* 文件名称,String
*/
String fileName;
/**
* 构建器,通过参数文件名生成该类
* @param filename 文件名称,字符串,String
*/
public FileLib(String filename){
fileName = filename;
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
}
/**
* isOk(),检查文件是否正常
* @return 返回布林值,看文件是否准备好了
*/
public boolean isOk(){
boolean ok = false;
if(is != null){
ok = true;
}
return ok;
}
/**
* readChar(),读取一个UNICODE格式字符的值
* @return 返回读取的Unicode字符,整数值
*/
public int readChar(){
int ch = -1;
try{
byte[] barray = new byte[2];
int pp = dis.read(barray);
if((pp != barray.length)||(pp == -1)){
return ch;
}else{
ch = (barray[1] << 8)|(barray[0] & 0xff);
disIdx += barray.length;
}
}catch(Exception e){
e.printStackTrace();
}
return ch;
}
/**
* readString(),读取指定个数个字符,返回字符串
*/
public String readString(int length){
StringBuffer strbuf = new StringBuffer(length);
int tmp = readChar();
if(tmp == -1){
return null;
}
for(int i = 0 ; (i < length)&(tmp != -1) ; i++){
strbuf.append((char)tmp);
tmp = readChar();
}
return strbuf.toString();
}
/**
* reachAt(),到达指定的位置,准备读取下一个字节
* @param pos 位置,整数值
*/
public void reachAt(int pos){
close();
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
try{
dis.skipBytes(pos);
}catch(Exception e){
e.printStackTrace();
}
}
/**
* test(),对InputStream等类的功能进行测试
*/
public void test(){
close();
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
int size = 0;
try{
if(dis.markSupported()){
System.out.println(fileName+" is mark supported.");
}
System.out.println("aviable bytes are "+dis.available());
//dis.reset();
}catch(Exception e){
e.printStackTrace();
}
close();
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
reachAt(disIdx);
}
/**
* getSize(),通过对文件的遍历得到文件的大小,单位为字节byte。
* 重建一个DataInputStream对象,遍历后关闭。
* @return 文件大小,整数值
*/
public int getSize() {
close();
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
int size = 0;
try{
while(dis.read() != -1){
size++;
}
close();
is = getClass().getResourceAsStream(fileName);
dis = new DataInputStream(is);
reachAt(disIdx);
}catch(Exception e){
e.printStackTrace();
}
return size;
}
/**
* close(),关闭文件
*/
public void close(){
try{
if(dis == null){
System.out.println(fileName+" has not benn opened now!");
return ;
}
dis.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
本文地址:http://com.8s8s.com/it/it14344.htm