对于存储来说定义一个 CDirectFileStore 去 打开或创建一个文件,然后再定义一个 RStoreWriteStream 流 进 行写,这个流可以通过 CreateLC 方 法进行初始化,初始化时会返回一个 TStreamId 对 像,保存这个 TStreamId 对 像,把想要写入文件的信息通过这个 RStoreWriteStream 进 行写入,存储时可以定义多个 RStoreWriteStream 进 行存储数据,保存每个 RStoreWriteStream 返 回的 TStreamId 对 像,要区分这些保存不同对像的 RStoreWriteStream 时 就是根据不同的 TStreamId ,把这些信息保存到文件中进行区分是通过 CStreamDictionary( 流 字典)来进行区分的,流字典的作用就是把 TStreamId 及 一个全局惟一标识符绑定起来,然后存到文件中 .(如 : aStreamDic.AssignL(KUidScpApplication, id);)当然,对于 CStreamDictionary 存 到文件时也需要 RStoreWriteStream 对 像来进行存储,如何区分哪一个是 CStreamDictionary , 哪一个是本身的数据 呢 ? 是通过 CDirectFileStore 的 SetRoot 方 法 来 实现的 .
关于从文件中读取: 因为已经把各个流通过 TStreamId 及一个全局唯一标符识区分开来,这时读取 时要先把流字典读出来,通过流字典及全局唯一标识符可以得到 TStreamId , RStoreReadStream 只 需要这些 TStreamId 进行初始化后,就可以读取这些信息了, CDirectFileStream 不区分 写入的各个 RStoreWriteStream 的顺 序,但各个 RStoreReadStream 在读取 时要根据 RStoreWriteStream 写入的 顺序来读取。比如 RStoreWriteStream rws1 与 RStoreWriteStream rws2 , rs1 先写入 CDirectFileStore , rs2 后写 入,则读取得可以先通过 TStreamId 让 RStoreReadStream rrs1 先读取 数据,再让 RStoreReadStream rrs2 读取数 据 (rws1=rrs1,rws2=rrs2)
这里的流字典就相当于一个索引的作用。
代码
#include < f32file.h >
#include < s32file.h >
#include < s32stor.h >
#include < e32std.h >
// Constants
// Global Variables
LOCAL_D CConsoleBase * console; // write all messages to this
_LIT(KTextConsoleTitle, " Console " );
_LIT(KTextFailed, " failed, leave code = %d " );
_LIT(KTextPressAnyKey, " [press any key]/n " );
class ClassA: public CBase
{
public :
static ClassA * NewL(TDesC & aName,TInt32 aNo)
{
ClassA * self = ClassA::NewLC(aName,aNo);
CleanupStack::Pop();
return self;
}
static ClassA * NewLC(TDesC & aName,TInt32 aNo)
{
ClassA * self = new (ELeave) ClassA();
CleanupStack::PushL(self);
self -> ConstructL(aName,aNo);
return self;
}
// 下面是通过一个流来实例化
static ClassA * NewL(RReadStream & aStream)
{
ClassA * self = ClassA::NewLC(aStream);
CleanupStack::Pop();
return self;
}
static ClassA * NewLC(RReadStream & aStream)
{
ClassA * self = new (ELeave)ClassA();
CleanupStack::PushL(self);
self -> InternalizeL(aStream);
return self;
}
public :
// 想在流中保存需要添加下面的方法
void ExternalizeL(RWriteStream & aStream) const
{
aStream.WriteInt32L(iName -> Des().MaxLength());
aStream <<* iName;
aStream.WriteInt32L(iNo);
}
void InternalizeL(RReadStream & aStream)
{
if (iName != NULL)
{
delete iName;
iName = NULL;
}
TInt32 max = aStream.ReadInt32L();
iName = HBufC::NewL(aStream,max);
iNo = aStream.ReadInt32L();
}
// 构造方法
ClassA(){};
// 析构方法
~ ClassA()
{
delete iName;
iName = NULL;
}
void Display()
{
_LIT(Kfmt, " name=%S/nNo=%d/n " );
console -> Printf(Kfmt,iName,iNo);
}
private :
void ConstructL(TDesC & aName,TInt32 aNo)
{
iName = aName.AllocL();
iNo = aNo;
}
private :
TInt32 iNo;
HBufC * iName;
};
// ClassFather 这个保存两个 ClassA 对像
class ClassFather: public CBase
{
public :
static ClassFather * NewL(TDesC & aName)
{
ClassFather * self = ClassFather::NewLC(aName);
CleanupStack::Pop();
return self;
}
static ClassFather * NewLC(TDesC & aName)
{
ClassFather * self = new (ELeave)ClassFather();
CleanupStack::PushL(self);
self -> ConstructL(aName);
return self;
}
static ClassFather * NewL(RReadStream & aStream)
{
ClassFather * self = ClassFather::NewLC(aStream);
CleanupStack::Pop();
return self;
}
static ClassFather * NewLC(RReadStream & aStream)
{
ClassFather * self = new (ELeave)ClassFather();
CleanupStack::PushL(self);
self -> InternalizeL(aStream);
return self;
}
ClassFather()
{};
~ ClassFather()
{
delete iName;
iName = NULL;
delete ia1;
delete ia2;
ia1 = NULL;
ia2 = NULL;
};
public :
void ExternalizeL(RWriteStream & aStream) const
{
aStream.WriteInt32L(iName -> Des().MaxLength());
aStream <<* iName;
ia1 -> ExternalizeL(aStream);
ia2 -> ExternalizeL(aStream);
}
void InternalizeL(RReadStream & aStream)
{
if (iName != NULL)
{
delete iName;
iName = NULL;
}
TInt32 max;
max = aStream.ReadInt32L();
iName = HBufC::NewL(aStream,max);
ia1 = ClassA::NewL(aStream);
ia2 = ClassA::NewL(aStream);
}
void display()
{
_LIT(Kfmt, " father Name=%S/n " );
console -> Printf(Kfmt,iName);
ia1 -> Display();
ia2 -> Display();
}
private :
HBufC * iName;
ClassA * ia1;
ClassA * ia2;
void ConstructL(TDesC & aName)
{
iName = aName.AllocL();
_LIT(Ka1, " A1 " );
_LIT(Ka2, " A2 " );
TBuf < 10 > buf1(Ka1);
TBuf < 10 > buf2(Ka2);
ia1 = ClassA::NewL(buf1, 1000 );
ia2 = ClassA::NewL(buf2, 2000 );
}
};
LOCAL_D const KA = 10000 ; // classA
LOCAL_D const KFA = 10001 ; // classFather
void storeInfo()
{
// 定义两个 ClassA 对像
_LIT(Ka, " AAA " );
TBuf < 10 > bufa(Ka);
_LIT(Kb, " bbb " );
TBuf < 10 > bufb(Kb);
ClassA * a = ClassA::NewL(bufa, 3000 );
ClassA * b = ClassA::NewL(bufb, 4000 );
// 定义两个 ClassFather 对像
_LIT(Kfa, " fatherA " );
_LIT(kfb, " fatherB " );
TBuf < 20 > buffa(Kfa);
TBuf < 20 > buffb(kfb);
ClassFather * cf1 = ClassFather::NewL(buffa);
ClassFather * cf2 = ClassFather::NewL(buffb);
// 定义一个文件
_LIT(KFile, " c://filelx.txt " );
TFileName fn(KFile);
RFs ifs;
User::LeaveIfError(ifs.Connect());
CFileStore * fs = CDirectFileStore::ReplaceLC(ifs,fn,EFileWrite);
fs -> SetTypeL(TUidType(fs -> Layout()));
// 存储数据
RStoreWriteStream wsfather;
TStreamId fatherId = wsfather.CreateLC( * fs);
wsfather.WriteInt32L( 2 );
cf1 -> ExternalizeL(wsfather);
cf2 -> ExternalizeL(wsfather);
// wsfather<<cf1;
// wsfather<<cf2;
wsfather.CommitL();
CleanupStack::PopAndDestroy();
RStoreWriteStream as ;
TStreamId classAId = as .CreateLC( * fs);
as .WriteInt32L( 2 );
// as<<a;
// as<<b;
a -> ExternalizeL( as );
b -> ExternalizeL( as );
as .CommitL();
CleanupStack::PopAndDestroy();
CStreamDictionary * dic = CStreamDictionary::NewLC();
dic -> AssignL(TUid::Uid(KFA),fatherId);
dic -> AssignL(TUid::Uid(KA),classAId);
RStoreWriteStream wdic;
TStreamId dicId = wdic.CreateLC( * fs);
wdic <<* dic;
wdic.CommitL();
CleanupStack::PopAndDestroy();
CleanupStack::PopAndDestroy();
fs -> SetRootL(dicId);
fs -> CommitL();
CleanupStack::PopAndDestroy();
}
void restore()
{
// 读取文件信息
// 1 读取 CStreamDictionary ,根据流 id 得到流信息
// 2 每个流信息读取一个 Int 型,得到有几个对像
// 3 循环读取每个对像
RFs ifs;
User::LeaveIfError(ifs.Connect());
_LIT(Kfilename, " c://filelx.txt " );
TFileName filename(Kfilename);
CFileStore * fs = CDirectFileStore::OpenLC(ifs,filename,EFileRead);
CStreamDictionary * dic = CStreamDictionary::NewLC();
RStoreReadStream read;
read.OpenLC( * fs,fs -> Root());
read >>* dic;
CleanupStack::PopAndDestroy();
RStoreReadStream readclassA;
TStreamId classId = dic -> At(TUid::Uid(KA));
TStreamId fatherId = dic -> At(TUid::Uid(KFA));
readclassA.OpenL( * fs,classId);
TInt32 max ;
readclassA >> max;
_LIT(Kmax, " this max:%d " );
console -> Printf(Kmax,max);
ClassA * ca = ClassA::NewL(readclassA);
ca -> Display();
ClassA * ca1 = ClassA::NewL(readclassA);
ca1 -> Display();
console -> Getch();
console -> ClearScreen();
RStoreReadStream readfather;
readfather.OpenL( * fs,fatherId);
max = readfather.ReadInt32L();
console -> Printf(Kmax,max);
ClassFather * cf1 = ClassFather::NewL(readfather);
ClassFather * cf2 = ClassFather::NewL(readfather);
cf1 -> display();
console -> Getch();
console -> ClearScreen();
cf2 -> display();
CleanupStack::PopAndDestroy();
CleanupStack::PopAndDestroy();
ifs.Close();
}
// Local Functions
LOCAL_C void MainL( const TDesC & aArgs)
{
//
// add your program code here, example code below
//
// console->Write(_L("Hello, world!/n"));
storeInfo();
restore();
console -> Printf(_L( " Command line args: / " % S/ " /n " ), & aArgs);
}