本文共 3590 字,大约阅读时间需要 11 分钟。
由于接口能够扩展Connection,并可利用GFC创建对象,与其它常见Connection 实现之间存在着一些显著差异。其中一个最显著的差异是,即使当前文件不存在,也能成功调用Connector.open()。这在创建新文件或新目录时是很有必要的。但是,打开不存在文件的InputStream是非法的。
另一个差异是,在关闭输入或输出流后, 仍能保持打开状态。因此,在访问文件后调用方法FileConnction.close()是很重要的,这样做可以保证其它应用能访问该文件。相应地,利用OutputStream对文件做出的修改也不会立即对文件系统可见。这取决于实际的实现以及设备的操作系统。方法flush()可以保证缓冲区能够被清空,并且其中的内容可以写入实际文件中。
与其它Connection对象的另外一个差别是,通过方法set(),可以实现对象的重用。该方法主要用于目录转换。其思想是,如果在特定目录中构建了,则可以调用方法list()获得该目录的子文件和子目录的枚举。该枚举值的成员可作为参数被传递给set(),之后,原始就指向了这个特定的子文件或子目录。通常来说,set()的参数是已存在的其它子文件或目录的相对路径,或者是表示上层目录的“..”参数。
另外一个针对所有I/O操作的常见注意事项是,必须在异于GUI线程的其它线程中执行I/O操作。在使用 API时,这个建议同样适用。由于安全架构的原因,与文件相关的操作可能会发生用户提示,要求用户对操作进行确认,考虑到这一点,在异于GUI线程的其它线程中执行I/O操作尤为重要。如果在GUI线程中执行I/O操作,并且需要使用用户提示,则MIDlet就有可能会死锁。
2.2 安全
在用 API开发应用软件时,考虑API的安全隐患是非常重要的。为了保护用户的个人数据和整个系统的安全,文件操作是受限制的。只有在获得必须的许可后,才能执行文件操作;否则,将抛出SecurityException异常。因此在适当的时候使用捕获SecurityException的语句非常重要。
MIDP 2.0 MIDlet既可以是不可信的,也可以是可信的[SIGNMID]。在第一种情况下,设备无法确知MIDlet的由来和完整性,因此,在没有显式的用户许可时,不允许调用受限的API。也就是说,如果需要访问一个文件或目录,将会显示用户提示,而用户必须显式地确认该操作。
在MIDlet是可信的情况下,设备可以通过X.509证书判断MIDlet的由来和完整性。这些MIDlet可以根据安装时的安全域设置,自动地获得许可。此外,MIDlet需要在Java 应用描述符(Java Application Descriptor,JAD)文件中的属性MIDlet-Permission中包含文件操作许可。
共定义了下面两个有关 API的许可:
javax.microedition.io.Connector.file.read
javax.microedition.io.Connector.file.write
如果希望以READ模式打开文件,并获取文件的输入流,则第一个许可是必需的。在用类FileSystemRegistry注册监听器时,也需要第一个许可。如果希望以WRITE模式打开文件,并打开文件的输出流,则第二个许可是必需的。此外,诸如删除、修改目录之类的操作也需要写入许可。如果以READ_WRITE模式打开文件,则同时需要两个许可。这些许可包含在Read User Data Access 和Write User Data Access功能组中。
对许可的授权或否认取决于MIDlet安装到的安全域。某些安全域可以完全地授权许可,而其它域则可能仅在得到显式用户同意的情况下才允许授权。实现时,可以对每个域允许的许可进行定义。但是,仍希望第三方和不可信域按照表1的方式定义许可模式:
功能组 | 可信的第三方域 | 不可信的域 | ||
默认设置 | 允许的设置 | 默认设置 | 允许的设置 | |
Read User Data | Oneshot | Session, Blanket, | Oneshot | Oneshot, No |
Access | Oneshot, No | ||||
Write User Data Access | Oneshot | Session, Blanket, Oneshot, No | No | Oneshot, No | |
表1:允许的和默认的许可模式
表1实际上说明,每次创建文件或目录连接时,不可信的MIDlet总会弹出一个提示。此外,如果以READ_WRITE模式打开连接,将会出现两个提示,分别对应于两个许可。可信的第三方MIDlet的情况与此类似,但是用户可以手动地把该设置改为session,这样,在运行MIDlet时,用户就会仅被询问一次。值得注意的另外一点是,许可是以基于文件到文件的方式给出的。也就是说,用户在访问每个文件或目录时都会被提示。该范例中的MIDlet需要在文件系统中遍历,因此会出现多个用户提示,对于此类的MIDlet来说,上述情况尤其值得注意。这种情况能够有力地说明,在使用受限API时,为什么应该对MIDlet签名。
此外,关于文件访问还有另外一个层面上的局限。根据安装时赋给MIDlet的安全域,MIDlet将能够访问文件系统的一个子集。这种设计可以保护用户数据,并可防止对操作系统的损害。特别地,可信的第三方 和 不可信域中的 MIDlet仅能访问一组被指定的公共目录(其中包括存放图象、视频、公共文件的目录)以及每个MIDlet的专用目录。这是推荐使用虚拟目录的原因之一,因为,有可能允许访问根目录Images/,但可能由于MIDlet无法访问e:,从而造成无法从e:/ 切换到目录e:/Nokia/Images/。
某些文件相关操作会检查是否获得了适当的安全许可,但是,在调用方法Connector.open()时,开发人员需要给予特别考虑。在创建和授权适当的许可后,对于需要同样许可的其它操作来说,该许可仍然有效。例如,一旦为写操作创建,则调用删除(delete)操作也已经被授权。如果创建的仅具有对读操作的许可,则在调用方法delete()时,将会要求对写操作的许可,在必要时,还将出现用户提示。
方法set()还将根据原始的创建模式检查文件许可。这是非常合理的,因为set能够改变当前连接,以便指向不同的文件或目录。
2.3 特有的目录
在许多设备中,一些目录是针对特定任务而设计的。例如,照相机设备在特定的“图像”目录下存储拍下的照片。为了使开发人员更加容易地访问此类目录,实现了 API的设备包含额外的系统属性,以用于定位这些目录。
并不是所有设备都需要这些属性,因此,不要想当然地认为它们存在。开发人员应该注意,如果属性值为null,则需寻找一个替代方法。
表2列举了系统属性。第一列是属性名,它以URL的格式指向特定目录。该URL可以被直接传递给Connection.open()。第二列是一个额外的属性,它包含该目录的本地化名称。建议用第二列中的属性代替目录的通用的非本地化名称,以保持MIDlet与其它设备UI的兼容性。
属性 | 局部属性 | 描述 |
fileconn.dir.photos | fileconn.dir.photos.name | 该属性指向的目录存储集成照相机拍下的相片或其它图象。 |
fileconn.dir.videos | fileconn.dir.videos.name | 与上面类似,但是存储的内容是视频。默认情况下,下载的视频也保存在该目录下。 |
fileconn.dir.tones | fileconn.dir.tones.name | 铃声或其它类似的音频文件存储在该目录下。 |
fileconn.dir.memorycard | fileconn.dir.memorycard.name | 在内存卡可用的情况下,该属性指向内存卡的根目录。 |
fileconn.dir.private | fileconn.dir.private.name | MIDlet套件的专用工作目录。 |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126442/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10294527/viewspace-126442/