Symbian 的任何对像都可以流化,只要有公共的 ExternalizeL 及 InternalizeL 方法即可,这两个方法的定义为:
void ExternalizeL(RWriteStream& aStream) const; void InternalizeL(RReadStream& aStream) ; |
注意:任何已定义 ExternalizeL 及 InternalizeL 的类都可以使用 << 及 >> 进行外部或内部化
对于定义有 ExternalizeL 及 InternalizeL 的类如果有类 成员变量 ,则在流化时可以从 ExternalizeL 中调 用类成员变量的 ExternalizeL ,如:
void CStudent::ExternalizeL(RWriteStream& aStream) { iTeacher->ExternalizeL(aStream); } |
文件流 常用 RFileWriteStream 及 RFileReadStream 来操作文件。
存储流 : 存储基本上是流的集合,可以存储多种数据类型,主要来看一下 CDirectFileStore ( 继承关系 : CFileStore- CPersistentStore- CStreamStore-CBase ) ,要通过 #include<s32store.h> 添加引用 ,library 也要添加 estor.lib .
初始化一个
CDirectFileStore
可以通过
Create
或
From
或
Replace
等
,Create
用于不存在一个文件,
From
用于通过一个已经打开的文件,
Replace
是对于没有的文件则创建,存在的文件进行替换。
如果已经创建一个 CDirectFileStore ( 或 CStreamStore ) ,则可以通过一个 SetTypeL 去指定存储的类型 .再创建一个用于流出或流入的对像 RStoreWriteStream 或 RStoreReadStream 对像,此俩对像创建时需要一个 CDirectFileStore 对像作为参数 ( TStreamId id = stream. CreateLC (aStore); ),在创建一个 RStoreWriteStream 时 , 会返回一个 TStreamId 对像,这个对像用来唯一标识一个流 .例 :
void CScpDocument::StoreL (CStreamStore& aStore , CStreamDictionary& aStreamDic ) const
{
RStoreWriteStream stream;
TStreamId id = stream.CreateLC (aStore);
CScpDisplayPreferences* preferences = iController->GetPreferences();
stream << *preferences; //will call CScpDisplayPreferences::ExternalizeL to output setting value.
// stream << *preferences; == preferences-> ExternalizeL(stream)
stream.CommitL ();
CleanupStack::PopAndDestroy ();
aStreamDic .AssignL (KUidScpApplication, id );
}
然后可对这个 RStoreWriteStream 或 RStoreReadStream 进行流出或流入操作 . 如 : stream << *preferences;
对于 RStoreReadStream 和 TStreamId 可以通过以下方式获得 . 例 :
void CScpDocument::RestoreL (const CStreamStore& aStore , const CStreamDictionary& aStreamDic)
{
TStreamId id = aStreamDic.At (KUidScpApplication);
CScpDisplayPreferences* preferences = iController->GetPreferences();
RStoreReadStream stream;
stream.OpenLC (aStore, id);
stream >> *preferences; //Will call CScpDisplayPreferences::InternalizeL to get setting value.
// stream >> *preferences; == preferences->InternalizeL(stream);
CleanupStack::PopAndDestroy ();
}
通过 CStreamDictionary 类可以将一个流 ID 与一个唯一值绑定起来 .
对于 CStreamDictionary 常用于把数据存储到 root 或取出 ID 后从 root 读出 . 存储 CStreamDictionary 时需要通过 RStoreWriteStream 来流出 , 读取时需要通过 RStoreReadStream 来流入 . Root 可以用 CDirectFileStore 的 SetRoot 方法去指定。
RStoreWriteStream 处理完后,要通过 CommitL ()提交, CDirectFileStore 也需要通过 Commit ()提交 (基类 CStreamStore 没有 Commit 方法 )
备注 :
对于存储来说定义一个 CDirectFileStore 去打开或创建一个文件,然后再定义一个 RStoreWriteStream 流 进行写,这个流可以通过 CreateLC 方法进行初始化,初始化时会返回一个 TStreamId 对像,保存这个 TStreamId 对像,把想要写入文件的信息通过这个 RStoreWriteStream 进行写入,存储时可以定义多个 RStoreWriteStream 进行存储数据,保存每个 RStoreWriteStream 返回的 TStreamId 对像,要区分这些保存不同对像的 RStoreWriteStream 时就是根据不同的 TStreamId,把这些信息保存到文件中进行区分是通过 CStreamDictionary( 流字典)来进行区分的,流字典的作用就是把 TStreamId 及一个全局惟一标识符绑定起来,然后存到文件中.(如: aStreamDic.AssignL(KUidScpApplication, id);)当然,对于 CStreamDictionary 存到文件时也需要 RStoreWriteStream 对像来进行存储,如何区分哪一个是 CStreamDictionary , 哪一个是本身的数据 呢 ? 是通过 CDirectFileStore 的 SetRoot 方法 来实现的 .
SetRootL(TStreamId)
inline void SetRootL(TStreamId anId);
Description
Sets the specified stream as the root stream.
Parameters
|
关于从文件中读取: 因为已经把各个流通过 TStreamId及一个全局唯一标符识区分开来,这时读取时要先把流字典读出来,通过流字典及全局唯一标识符可以得到 TStreamId, RStoreReadStream 只需要这些 TStreamId 进行初始化后,就可以读取这些信息了, CDirectFileStream 不区分写入的各个 RStoreWriteStream 的顺序,但各个 RStoreReadStream 在读取时要根据 RStoreWriteStream 写入的顺序来读取。比如 RStoreWriteStream rws1 与 RStoreWriteStream rws2 , rs1 先写入 CDirectFileStore , rs2 后写入,则读取得可以先通过 TStreamId 让 RStoreReadStream rrs1 先读取数据,再让 RStoreReadStream rrs2 读取数据 (rws1=rrs1,rws2=rrs2)