*文件服务器
- 通过客户端API进行访问,该API在f32file.h中定义
(驱动器A——Z:C是系统内置存储位置,Z是ROM只读内存保留的,其他的可以任意分配)
*文件服务器会话
- 所有的文件都是通过会话进行访问
- 应用程序可能有多个会话
- 使用RFs类开启会话
*连接到文件服务器
- 增加资源数
- 必须在完成操作之后关闭资源,比如
RFs fsSession;
User::LeaveIfError(fsSession.Connect());
……
fsSession.Close();
*使用CONE环境提供的实例,比如:
RFs& fs = CCoeEnv::Static()->FsSession();
*RFs功能包括
- 添加、删除、移动和重命名文件和目录
- 获取目录列表
- 保持包含驱动器盘符和路径的默认路径
- 获取驱动器和卷的信息
- 请求重要修改的通知事件
*如下的文件访问示例中,CDir类包含目录列表
RFs& fs = CCoeEnv::Static()->FsSession();
CDir* anEntryList = NULL;
_LIT(KPath,"c://nokia//");
User::LeaveIfError(fs.GetDir(KPath, KEntryAttNormal, ESortByName, anEntryList));
//迭代访问该列表
for (TInt I=0; i<anEntryList->Count(); I++)
{
const TEntry& anEntry = (*anEntryList)[I];
TBuf<KMaxFileName> name = anEntry.iName;
TUInt IAttributes = anEntry.IAtt;
TInt iSize = anEntry.iSize;
}
delete anEntryList;
anEntryList = NULL;
读/写文件
*RFile类
- 提供句柄以打开单个文件
- RFile::Create()打开一个新文件用于写入
- RFile::Open()打开一个已有文件用于访问
- RFile::Replace()删除已有文件并打开一个新文件,或者在该文件不存在的情况下直接创建一个新文件
- RFile::Flush()将缓存的数据写入文件
- RFile::Close()关闭文件
*读写文件方法
- RFile::Read()和RFile::Write()
- 只适用于8位二进制数据或是ASCII文本
- 不能用于其他数据类型
- 流更适用于文件读写操作
使用RFile操作二进制数据
*访问二进制数据
*RFile类表示一个文件
*一旦打开文件,就可以读/写数据
- RFile::Read()
- RFile::Write()
*文件数据作为二进制数据或ASCII文本进行处理
*使用字节描述符
- TDes8,TDesC8,等
*Series60只支持Unicode,所以使得该函数适用性有限
*删除文件和目录
- 文件不能处于打开状态或是只读状态
- 不能删除系统文件
- 目录必须为空
- 不能删除根目录
- 对于文件使用RFs::Delete(), 对于目录使用RFs::RmDir()
流化
*流对数据(通常是对象)的外部存储进行抽象
*流化API是抽象的
- 它提供从存储读取数据和向存储写入数据的接口,但是不关心存储是什么
- 定义于s32std.h,文件流定义于s32file.h
·该头文件与estor.lib相联
*基于两个关键概念
- 流
- 流操作符
流
*数据结构(比如对象)的外部表示,其形式是二进制数据序列
*通过读/写流访问
*设计用于流实现的C++类
- ExternalizeL()
·外部化流状态
— InternalizeL()
·内部化流状态
*优点
- 更适用于原始文件操作
- 使用起来更加容易
外部化
*外部化对象的过程也就是将该对象的数据写入流中
*对于一个类的实例,该过程包括将其数据成员和组件外部化到流中
*该过程封装在该类的成员函数ExternalizeL()中
*使用类RWriteStream的写入流接口
- 允许ExternalizeL()将对象数据写入流中,而不关心流的具体实现方式
*类一般按照如下的方式定义ExternalizeL()函数
void ExternalizeL(RWriteStream& aStream) const;
写入流
*该操作由抽象类RWriteStream表示
- 提供必需的接口,以实现外部化到流的操作
*RFileWriteStream继承自RWriteStream,并且提供关联到文件的接口
- 也存在其它的具体实现,比如RStoreWriteStream
*RWriteStream提供对如下对象外部化的支持
- TInt,TUint,TReal和TReal64类型
- 描述符的内容
- 来自于开启的读取流对象的数据,类型为RReadStream
*直到调用RWriteStream::CommitL()将流缓冲写入流,流的写入操作才执行
写入流-示例
*使用RFileWriteStream::Create()创建文件
*使用RFileWriteStream::Open()打开已经存在的文件
RFs& fs = CCoeEnv::Static()->FsSession();
RFileWriteStream writeStream;
User::LeaveIfError(writeStream.Create(fs,KTxtFileName,EFileWrite));
writeStream.PushL(); /压入清理栈
iObject.ExternalizeL(writeStream);
/清理工作
writeStream.CommitL();
writeStream.Pop();
writeStream.Release();
内部化
*内部化一个对象的过程也就是将该对象的数据从流中读出
*对于一个类的实例,该过程包括将其数据成员和组件从流中读出
- 内部化的顺序和外部化的顺序相同
*该过程通过该类的InternalizeL()成员函数封装
*使用读取流接口类RReadStream
- 允许函数InteranlizeL()从流中读取对象的数据,而不用考虑流的具体实现
*类通常按照如下的方式定义InternalizeL()
void InternalizeL(RReadStream& aStream);
读取流
*由抽象类RReadStream表示
- 提供从流中内部化的必要接口
*RFileReadStream继承自RReadStream,提供与文件关联的接口
- 也存在其它形式的具体实现,比如RStoreReadStream
*RReadStream针对如下数据提供内部化的支持
- TInt,TUint,TReal和TReal64类型
- 描述符的内容
读取流-示例
*使用RFileReadStream::Open()打开文件
RFs& fs = CCoeEnv::Static()->FsSession();
RFileReadStream readStream;
User::LeaveIfError(readStream.Open(fs,KTxtFileName,EFileRead));
readStream.PushL();/压入清理栈
iObject.InternalizeL(readStream);
/清理工作
readStream.Pop();
readStream.Release();
流操作符
*有两种模板化的流操作符:operator<<和operator>>
*用于外部化和内部化各种类型的数据
*使用与C++输入输出流相类似的语法
*该操作符的实现取决于其调用对象的类型
/可以使用写入流将一个对象外部化到流中
writeStream << object;
...
/此后,还可以通过读取流将该数据内部化
readSteam >> object;
标准类型和类
*存储框架为外部化和内部化操作符提供了必要的实现,包括
- 基本类型,比如TInt8,TUint8,TReal32 等等
- 图形API类,比如TPoint,TSize和TRect
- UID操作API类,比如TUid
- 动态缓冲API类,比如CBufFlat和CBufSeg
*针对内置类型和类使用流操作符时
- << 操作符解析为与内置类型或类相关联的RWriteStream函数
·比如RWriteStream::WriteInt8L(TInt aValue) 等等
- >> 操作符解析为与内置类型或类相关联的RReadStream函数
·比如RReadStream::ReadInt8L()等等
可序列化类
*可序列化类是定义和实现ExternalizeL()与InternalizeL()的类
*对于这种类,存储框架
- 通过调用该类的ExternalizeL()成员函数来实现操作符 <<
- 能过调用该类的InternalizeL()成员函数来实现操作符 >>
例如iObj是可序列化类的对象
iObj.ExternalizeL(writeStream)
等同于
writeStream << iObj
iObj.InternalizeL(readStream)
等同于
readStrem >> iObj
序列化TInt
*TInt是特殊的情况
- 定义一个最小尺寸(所占空间)
- 实际尺寸是由平台决定的
*不能使用操作符<<或>>来序列化TInt
*必须使用函数来指定外部尺寸
非类类型
*比如枚举类型
*对于非类类型,需要定义和实现特定的操作符
- 操作符定义必须和模板定义一致
*举例来说,对于枚举类型TXxx,操作符应该按照如下的方式进行实现
RWriteStream& operator << (RWriteStream& aStream, const TXxx& anXxx)
{
aStream WriteInt8L(anXxx);
return aStream;
}
RReadStream& operator >> (RReadStream& aStream, TXxx& anXxx)
{
anXxx = TXxx(aStream.ReadInt8L());
}
不可序列化类
*该类不定义和实现ExternalizeL()与InternalizeL()函数
*通过定义和实现一些额外的全局函数,仍可以对该类进行序列化操作
*实际上,为某个类定义和实现ExternalizeL()与InternalizeL()更加简单
*但是,在少数情况下,不需要定义该函数,比如,移植类的时候
*所有新建的类应该包含该函数
外部化描述符
*使用RWriteStream类的WriteL()函数
- 只将描述符的内容写入流中
- 它们并不会写入任何的长度信息
*使用模板化的流操作符<<
- 由存储框架实现,将描述符的内容和长度都写入流中
- 更适用于描述符,因为可以很方便地进行内部化
·对应的操作符>>
·重载HBufC::NewL()或HBufCL::NewLC()可以将读取流作为参数
内部化描述符
*使用RReadStream类的Real()成员函数
- 假设流中只包含描述符的内容
*使用模板化的流操作符>>
- 由存储框架实现,从流中读取描述的内容和长度
- 重载HBufC::NewL()或HBufC::NewLC()可以将读取流作为参数
- 在从流中内部化之前,需要分配堆描述符
*最后两项的前提假设是描述符是使用模板化的操作符<<进行外部化的
内部化不可修改的描述符
*不能直接将数据读取写入不可修改的描述符中(TBufC,TPtrC,HBufC):
- 不可修改的API,故没有重载的>>操作符
- 使用::Des()创建可修改的描述符
- 使用可修改的描述符来访问不可修改的描述符拥有的内存
TBufC iDataItem1;
TPtr modifiableDataItem1 = iDataItem1.Des();
aStream >> modifiableDataItem1;
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pandahsu/archive/2009/07/14/4346847.aspx
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pandahsu/archive/2009/07/14/4346841.aspx