对文本文件的存取 
  要看书得有书才行,不可能把书本认为分段以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();         }     }      }   
 
  |