Symbian编程总结-文件、流与数据库-文件系统及相关API(1)
本文章由杨芹勍原创,如需转摘请注明出处。谢谢!
前几篇文章介绍的都是一些Symbian编程的基础知识。趁大家还没有开始感觉到枯燥乏味的时候,我们来学习一些有意思的东西:Symbian中的文件处理。在文章的最后将和大家从头开始,制作一个类似于DOS的简单目录文件管理器。
注:本文所描述的内容对应的终端系统为Series 60 3rd。
一、Symbian OS 文件系统
1、Symbian OS中的文件名与路径名
- Symbian OS的文件名及路径名命名规则类似于Dos/Windows,如“c:\resource\1.png”,文件名和路径名可以保存为大小写且不区分大小写。
- 文件名和路径名可以带空格,但不能包含以下字符:<、>、"、/、|
- 驱动器c:为系统分区,d:为虚拟缓冲盘,e:为存储卡,z:为系统只读驱动器;
- 文件或目录的完整路径名(包括盘符、子目录)的长度不能超过256个字符;
具体细节请参看SDK文档: » Symbian OS reference » C++ component reference » Base F32 » RFs
2、应用程序访问路径的能力说明
S60第三版加入了数字签名验证,应用程序要使用某些系统资源得拥有相应的能力,而这些能力必须得通过SymbianSigned签名验证应用程序才能发布。关于各个能力的说明,请参看Symbian S60 3rd中的能力说明这篇随笔。
应用程序对特定目录的访问也有限制,以下表格列出了访问相应目录所需要的能力:
目录 (包括子目录) | 需要的能力 | |
读访问 | 写访问 | |
resource | None | TCB |
sys | AllFiles | TCB |
/private/<ownSID> | None | None |
/private/<otherSID> | AllFiles | AllFiles |
/<other> | None | None |
这里的SID指的是应用独有的安全ID(SecureID).每个应用都有自己的安全ID及按照安全ID而定义的独有的私有目录,如c:/private/20000001。 应用的SecureID一般是由在工程文件.mmp中的UID3来决定的(如果没有特别定义的话)。
二、操作文件系统的相关API
1、连接文件服务器并管理文件系统的RFs类
与Windows不同,Symbian OS中有专门的服务(进程)去管理文件的读写。我们通过使用RFs类去连接文件服务器,操作并访问文件系统。
RFs派生于RSessionBase,为一个服务器会话类。
- 在控制台程序里,我们使用以下代码创建RFs并连接到文件服务器:
1 RFs fs; 2 CleanupClosePushL(fs); 3 User::LeaveIfError(fs.Connect()); 4 5 ... 6 7 CleanupStack::Pop(&fs);
- 如果我们使用了GUI应用程序框架,框架已经为我们封装好了RFs,并且已经连接,我们只需要使用以下方法获取:
RFs& fs = CEikonEnv::Static()->Static()->FsSession();
注意:程序退出的时候必须保证每一个手动连接都关闭,即使用RFs::Close()方法,否则会CONE 36 Panic:“Open handles were found during application shutdown”也就是说程序在退出时还有系统资源没有释放。
RFs为对文件系统执行相关操作的类,其中的函数使用非常简单,细节大家可以参考SDK文档。以下列出几个比较常用的函数:
- Connect和Close:刚才已经介绍过,连接文件服务器及关闭连接;RFs::Connect()和RFs::Close()是一一对应的。 上面代码中GUI应用框架暴露的RFs不需要显示的关闭,框架在退出的时候已经为我们关闭了。
- MkDir和MkDirAll:创建新的目录,MkDir要保证上级目录存在,MkDirAll会检查上级目录和祖先目录,如果不存在也会创建他们;
- Rename:重命名文件或目录;
- RmDir:删除目录,目录必须不为空且不为根目录;
- Att和SetAtt:获取/设置文件或目录属性;
- SessionPath:返回当前路径;
- SetSessionPath:设置当前路径,不能包含文件名;
- ……
2、针对文件操作的RFile类
RFs类提供了对文件系统的管理,RFile类提供了对单一文件及文件内容的管理。
RFile类派生于RSubSessionBase,为一个服务器子会话,他需要建立在RFs的会话上与服务器通信。
以下列出几个常用的API并做简单的解释:
- Close:关闭文件,与其他语言类似,在关闭文件前,需要调用RFile::Flush将缓冲区的内容写入存储。注意:当父会话RFs关闭的时候,文件也会被关闭;
- Open:打开文件,此函数非常重要,原型为:
IMPORT_C TInt Open(RFs& aFs,const TDesC& aName,TUint aFileMode);
- Read:读取文件内容,此函数带有同步版本和异步版本的函数重载;
- Write:将内容写入文件,此函数也带有同步和异步的重载版本;
- Seek:根据跳转模式将文件指针跳转到文件指定的位置;
- Size/SetSize:获取/设置文件大小;
- Att/SetAtt:获取/设置文件属性;
- ……
3、针对文件及路径解析的TParse(TParsePtr、TParsePtrC)类
TParse及相关类提供一套检测及解析文件路径的函数,你可以使用TParse获取文件路径的盘符、扩展名、路径、文件名等。
TParse与TParsePtr(TParsePtrC)的区别:
- TParse不包含所要解析的文件路径描述符,使用Set()方法传递文件路径描述符给TParse类;
- TParsePtr(TParsePtrC)包含文件路径,在构造函数中传入文件路径描述符。
4、文件系统及文件的高级处理类CFileMan
CFileMan提供了很多比较高级的方法,如:批量复制文件、批量移动文件、删除文件夹包括所有子文件夹和文件等等。这些方法大多数都为异步函数,需要结合活动对象使用。此类我将在下一节详细介绍。
三、小演练:DOS命令目录文件管理器
因为我们还没有学习GUI应用程序框架,我们先以命令行入手,做一个简单的DOS命令目录文件管理器,让大家熟悉一下相关的API。
在这里我把所支持的命令及功能和所用到的API以表格的方式列出来供大家参考:
命令 | 参数 | 说明 | 所用到的API |
cd | 无 | 显示当前路径 | RFs::SessionPath |
. | 返回当前路径(不做任何处理) | ||
.. | 返回上级目录 | TParse::PopDir | |
\ | 返回根目录 | TParse::Drive | |
dir | 无 | 列出当前路径的文件和文件夹并显示出属性和修改时间 | RFs::GetDir RFs::Att RFs::Modified RFile::Att RFile::Modified |
路径名 | 列出指定路径的文件和文件夹并显示出属性和修改时间 | ||
type | 文件名 | 显示文件内容 | RFile::Open RFile::Read |
md | 路径名 | 创建目录 | RFs::MkDirAll |
rd | 路径名 | 删除目录,目录必须为空 | RFs::RmDir |
del | 文件名 | 删除一个文件 | RFs::Delete |
drivers | 无 | 列出所有驱动器(包括卷标名) | RFs::DriveList RFs::Volumn |
label | 驱动器名 卷标名 | 设置驱动器卷标 | RFs::SetVolumnLabel |
ren | 文件名或路径名 新名称 | 改变文件或路径名称 | RFs::Rename |
四、参考文献
- Series 60 应用程序开发
- 应用开发 S60 3rd Edition