文件流与存储流(转+修正)

来源:互联网 发布:linux文件夹权限修改 编辑:程序博客网 时间:2024/05/30 04:29

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

    {      

      RStoreWriteStreamstream;

      TStreamId id = stream.CreateLC(aStore);  

      CScpDisplayPreferences*preferences = iController->GetPreferences();   

      stream<< *preferences; //will call CScpDisplayPreferences::ExternalizeL to outputsetting value.

// stream <<*preferences; == preferences-> ExternalizeL(stream)

      stream.CommitL();

      CleanupStack::PopAndDestroy();

      aStreamDic.AssignL(KUidScpApplication,id);

    }

然后可对这个RStoreWriteStreamRStoreReadStream 进行流出或流入操作. : stream <<*preferences;

对于RStoreReadStream TStreamId 可以通过以下方式获得. :

void CScpDocument::RestoreL(constCStreamStore& aStore, const CStreamDictionary&aStreamDic)

    {   

      TStreamId id = aStreamDic.At(KUidScpApplication);

      CScpDisplayPreferences*preferences = iController->GetPreferences();

     

      RStoreReadStreamstream;

      stream.OpenLC(aStore,id);

      stream>> *preferences; //Will call CScpDisplayPreferences::InternalizeL to getsetting value.

// stream >>*preferences; == preferences->InternalizeL(stream);

      CleanupStack::PopAndDestroy();     

    }

通过CStreamDictionary 类可以将一个流ID与一个唯一值绑定起来.

对于 CStreamDictionary 常用于把数据存储到root 或取出ID后从root读出.存储CStreamDictionary 时需要通过RStoreWriteStream来流出, 读取时需要通过RStoreReadStream来流入. Root 可以用CDirectFileStoreSetRoot方法去指定。

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)

inlinevoid SetRootL(TStreamId anId);

Description

Sets the specified stream as theroot stream.

Parameters

TStreamId anId

The id of the stream which is to be the root stream of this store.

 

关于从文件中读取:因为已经把各个流通过TStreamId及一个全局唯一标符识区分开来,这时读取时要先把流字典读出来,通过流字典及全局唯一标识符可以得到TStreamIdRStoreReadStream只需要这些TStreamId 进行初始化后,就可以读取这些信息了,CDirectFileStream 不区分写入的各个 RStoreWriteStream 的顺序,但各个 RStoreReadStream 在读取时要根据 RStoreWriteStream 写入的顺序来读取。比如 RStoreWriteStream rws1 RStoreWriteStream rws2 rs1先写入CDirectFileStorers2 后写入,则读取得可以先通过 TStreamId RStoreReadStream rrs1 先读取数据,再让 RStoreReadStreamrrs2 读取数据(rws1=rrs1,rws2=rrs2)