最近在我的J2ME项目中,我想把JSR75的FileConnection类包装成类似J2SE中的File类来对文件进行操作,所以研究了FileConnection类的行为和在不同机器上的实现,以寻求最小的功能集合。之所以要抽象出一个File类,是因为我想将来用RMS模拟出一个文件系统。
?
这个File类能够通过简单的构造函数File(String path)来创建,并且提供部分FileConnection的功能。当然更重要的是提供简单的读写函数read(byte[] data),write(byte[] data)和获得InputStream,OutputStream。于是,接下来就要研究一下对于同一个文件,不同的操作系统,能够同时打开多少个FileConnection和多少个输入输出流。
?
在这之前,还有一个不能忽视的问题。J2ME系统对一些敏感的API进行了安全保护,没有签名的MIDlet如果要访问这些受保护的API,系统将会暂停当前程序并给用户一个提示,并由用户选择是否允许不受信任的程序访问这些API。
?
有些系统,如Moto和Siemens,对于FileConnection的访问可以选择只在第一次调用的时候询问,之后直到程序退出,都不会再向用户发出询问。也就是用户的选择可以在当前的整个会话Session中有效。
而对于目前相对主流的Symbian S60 v3系统则不是,每次调用FileConnectionAPI都会发出询问(没有"Session有效"的选项)。如果软件中有很多对文件的操作,不断弹出的系统提示必然会影响用户体验。想完全回避这些提示的唯一方法就是对软件进行签名。但是在S60 v3的系统下,对于我们开发者来说,想要签名一个MIDlet并且被系统承认几乎是不可能的。因为S60 v3系统中内置根证书签发机构的证书费用都非常昂贵,一年要上千美刀。
?
对于S60系统,我们能做的可能就是在软件中尽量少的出现这种系统提示,这就需要知道系统到底在调用FileConnection什么方法时才会弹出提示。于是我写了几行代码进行了测试。
?
在S60 v3 模拟器和Nokia E70上运行后得出,所有的安全提示只会在执行Connector.open方法时才会出现,FileConnection对象返回以后,调用它的任何方法都不会再出现提示。在Connector.open中如果用只读的方式创建FileConnection只会出现一次提示,如果用读写方式,则会连续的出现两次提示(一次读确认一次写确认)。在Moto的模拟器上测试,只读和读写方式分别只弹出一次提示,并且可以Session有效。
?
下面我又写了几行代码,测试了对于一个物理文件来说,可以同时创建多少个不同的FileConnection,获得多少个不同的InputStream和OutputStream。在WTK,S60 v3模拟器,Moto模拟器上测试,结果如下:
Moto模拟器和WTK的结果完全一样,怀疑Moto的是基于WTK的(很多地方他俩都很相似)。
?
OOM:一直跑到系统抛出OutOfMemory错误(我机器内存小啊),实际系统支持的最大数量无法测到,不过肯定是够用了。
?
软环境:JRE6.0+Windows Server 2003
? | WTK,Moto模拟器 | S60 v3模拟器 |
1个文件能创建的FileConnection实例数 | OOM(5000+) | OOM(1000+) |
1个文件能创建的InputStream实例数(通过不同的FileConnection对象获得) | 2043 | 1 |
1个文件能创建的OutputStream实例数(通过不同的FileConnection对象获得) | 1021 | OOM |
1个FileConnection对象可返回的InputStream数 | 1 | 1 |
1个FileConnection对象可返回的OutputStream数 | 1 | 1 |
1个文件,FileConnectionA先打开一个InputStream,FileConnectionB再打开一个OutputStream | 成功 | IOException |
1个文件,FileConnectionA先打开一个OutputStream,FileConnectionB再打开一个InputStream | 成功 | 成功 |
这样的结果真是奇怪,反正最终得到,在S60 v3的机器上,一个文件只能且仅能通过同一个FileConnection对象得到一个InputStream和一个OutputStream。
?
另外,对于从Jar压缩包中读取文件,用getClass().getResourceAsStream(String path)得到InputStream,在所有测试平台上都是OOM。
?
由于WTK是建立在PC上的,它的J2ME实现有时候过于强大,功能太完善,往往迷惑了我们的眼睛。把程序拿到其他模拟器甚至是机器上,很多东西就不是那么回事了。要小心啊。