文件流与存储流
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 ,要通过 #include<s32store.h> 添加引用,library 也要添加estor.lib
初始化一个 CDirectFileStore 可以通过 Create 或 From 或 Replace 等 ,Create 用于不存在一个文件,From 用于通过一个已经打开的文件,Replace
是对于没有的文件则创建,存在的文件进行替换。
如果已经创建一个 CDirectFileStore ,则可以通过一个 SetTypeL 去指定存储的类型
再创建一个用于流入的对像 RStoreWriteStream 或 RStoreReadStream 对像,这个对像创建时指定一个 CDirectFileStore 对像,然后对这个RStoreWriteStream
或 RStoreReadStream 进行流入或流出操作,在创建一个 RStoreWriteStream 或 RStoreReadStream 时会返回一个 TStreamId 对像,这个对像用来唯一标识一个流
通过 CStreamDictionary 类可以将一个流ID与一个唯一值绑定起来,对于 CStreamDictionary 常用于存储到 root,存储 CStreamDictionary 时也需要通过
RStoreWriteStream 来流入,然后用 CDirectFileStore的SetRoot方法去指定。
RStoreWriteStream 处理完后,要通过 CommitL()提交,CDirectFileStore 也需要通过 Commit()提交
下面是练习的代码,根据上面说的再来看代码就能更清楚的理解了 CStudent CStudent CStudent CStudent::CStudent() CStudent::CStudent( TInt32 aNo,TInt32 aScore ) CTeacher CTeacher CTeacher } CTeacher::CTeacher() CTeacher::CTeacher( TInt32 aNo,TInt32 aAge ) TBuf CArrayFixFlat stuList CFileStore CStreamDictionary RStoreWriteStream stuStream; RStoreWriteStream tecStream; dictionary RStoreWriteStream root; CFileStore CStreamDictionary RStoreReadStream rootStream; TStreamId sid _LIT(kfmt,
#include <e32base.h>
#include <e32std.h>
#include <e32cons.h> // Console
#include <s32file.h>
#include <f32file.h>
#include <s32std.h>
#include <s32stor.h>
// Constants
_LIT(KTextConsoleTitle, "Console");
_LIT(KTextFailed, " failed, leave code = %d");
_LIT(KTextPressAnyKey, " [press any key]\n");
// Global Variables
LOCAL_D CConsoleBase* console; // write all messages to this
// 定义两个流 id
LOCAL_D const KStuDataStreamId=0x101F613F;
LOCAL_D const KTeachDataStreamId=0x101F6140;
class CStudent:public CBase
{
public:
static CStudent* NewL(TDesC& aName,TInt32 aNo,TInt32 aScore);
static CStudent* NewLC(TDesC& aName,TInt32 aNo,TInt32 aScore);
~CStudent();
static CStudent* NewLC(RReadStream& aStream);
public:
void ExternalizeL(RWriteStream& aStream) const;
void InternalizeL(RReadStream& aStream);
void Display();
CStudent();
private:
CStudent(TInt32 aNo,TInt32 aScore);
void ConstructL(TDesC& aName);
private:
HBufC* iName;
TInt32 iNo;
TInt32 iScore;
};
{
CStudent* self = CStudent::NewLC(aName,aNo,aScore);
CleanupStack::Pop();
return self;
}
{
CStudent* self = CStudent::NewLC(aStream);
CleanupStack::Pop();
return self;
}
CStudent* CStudent::NewLC( TDesC& aName,TInt32 aNo,TInt32 aScore )
{
CStudent* self = new(ELeave) CStudent(aNo,aScore);
CleanupStack::PushL(self);
self->ConstructL(aName);
return self;
}
{
CStudent* self = new(ELeave)CStudent();
CleanupStack::PushL(self);
self->InternalizeL(aStream); // 同化 ?为什么要这样呢
return self;
}
CStudent::~CStudent()
{
delete iName;
iName = NULL;
}
void CStudent::ExternalizeL( RWriteStream& aStream ) const
{
aStream.WriteInt32L(iName->Des().MaxLength()); // 写入最大长度
aStream<<*iName; // 外化姓名
aStream.WriteInt32L(iNo);
aStream.WriteInt32L(iScore);
}
void CStudent::InternalizeL( RReadStream& aStream )
{
if (iName == NULL)
{
delete iName;
iName = NULL;
}
TInt32 max ;
max = aStream.ReadInt32L();
iName = HBufC::NewL(aStream,max);
iNo = aStream.ReadInt32L();
iScore = aStream.ReadInt32L();
}
void CStudent::Display()
{
_LIT(Kfmt,"name=%S\nno=%d\nscore=%d\n");
console->Printf(Kfmt,iName,iNo,iScore);
console->Getch();
}
{
}
{
iNo
iScore = aScore;
}
void CStudent::ConstructL( TDesC& aName)
{
iName = aName.AllocL();
}
//////////////////////////////////////////////////////////////////////////
class CTeacher:public CBase
{
public:
static CTeacher* NewL(TDesC& aName,TInt32 aNo,TInt32 aAge);
static CTeacher* NewLC(TDesC& aName,TInt32 aNo,TInt32 aAge);
~CTeacher();
static CTeacher* NewLC(RReadStream& aStream);
public:
void ExternalizeL(RWriteStream& aStream) const;
void InternalizeL(RReadStream& aStream);
void Display();
CTeacher();
private:
CTeacher(TInt32 aNo,TInt32 aAge);
void ConstructL(TDesC& aName);
private:
HBufC* iName;
TInt32 iNo;
TInt32 iAge;
};
{
CTeacher* self = CTeacher::NewLC(aName,aNo,aAge);
CleanupStack::Pop();
return self;
}
{
CTeacher* self = CTeacher::NewLC(aStream);
CleanupStack::Pop();
return self;
}
CTeacher* CTeacher::NewLC( TDesC& aName,TInt32 aNo,TInt32 aAge )
{
CTeacher* self = new(ELeave)CTeacher(aNo,aAge);
CleanupStack::PushL(self);
self->ConstructL(aName);
return self;
}
{
CTeacher* self = new(ELeave)CTeacher();
CleanupStack::PushL(self);
self->InternalizeL(aStream);
return self;
}
CTeacher::~CTeacher()
{
delete iName;
iName = NULL;
{
}
{
iNo
iAge = aAge;
}
void CTeacher::ExternalizeL( RWriteStream& aStream ) const
{
aStream.WriteInt32L(iName->Des().MaxLength());
aStream<<*iName;
aStream.WriteInt32L(iNo);
aStream.WriteInt32L(iAge);
}
void CTeacher::InternalizeL( RReadStream& aStream )
{
if (iName != NULL)
{
delete iName;
iName = NULL;
}
TInt32 max;
max = aStream.ReadInt32L();
iName = HBufC::NewL(aStream,max);
iNo = aStream.ReadInt32L();
iAge = aStream.ReadInt32L();
}
void CTeacher::Display()
{
_LIT(Kfmt,"Name=%S\nNo=%d\nAge=%d\n");
console->Printf(Kfmt,iName,iNo,iAge);
console->Getch();
}
void CTeacher::ConstructL( TDesC& aName )
{
iName = aName.AllocL();
}
void StoreL(RFs aFs,TDesC& aFileName)
{
_LIT(KName1,"hewei");
_LIT(KName2,"hewei_2");
_LIT(KName3,"Jianzhou_3");
_LIT(KName4,"Jianzhou_4");
TBuf<10> name2(KName2);
TBuf<10> name3(KName3);
TBuf<10> name4(KName4);
CStudent* stu1 = CStudent::NewL(name1,1,80);
CStudent* stu2 = CStudent::NewL(name2,2,90);
CTeacher* tec1 = CTeacher::NewL(name3,1,25);
CTeacher* tec2 = CTeacher::NewL(name4,2,30);
CArrayFixFlat<CTeacher>* tecList= new(ELeave)CArrayFixFlat<CTeacher>(4);
stuList->AppendL(*stu2);
tecList->AppendL(*tec1);
tecList->AppendL(*tec2);
store->SetTypeL(TUidType(store->Layout()));
TStreamId sid = stuStream.CreateLC(*store);
TInt32 numberOfStudents = stuList->Count();
stuStream<<numberOfStudents; // 写入数组长度
int i;
for (i=0;i<numberOfStudents;i++)
{
(*stuList)[i].ExternalizeL(stuStream); // 外部化数组元素
}
stuStream.CommitL();
CleanupStack::PopAndDestroy();
TStreamId tId
TInt32 numberOfTechers = tecList->Count();
tecStream<<numberOfTechers;
for (i=0;i<numberOfTechers;i++)
{
(*tecList)[i].ExternalizeL(tecStream);
}
tecStream.CommitL();
CleanupStack::PopAndDestroy();
dictionary->AssignL(TUid::Uid(KTeachDataStreamId),tId);
TStreamId rootid = root.CreateLC(*store);
root<<*dictionary;
root.CommitL();
CleanupStack::PopAndDestroy(); // root
CleanupStack::PopAndDestroy(); // dictionary
store->SetRootL(rootid);
store->Commit();
CleanupStack::PopAndDestroy(); // store
}
void RestoreL(RFs aFs,TDesC& aFileName)
{
CArrayFixFlat<CStudent>* stuList = new(ELeave)CArrayFixFlat<CStudent>(10);
CleanupStack::PushL(stuList);
CArrayFixFlat<CTeacher>* tecList = new(ELeave)CArrayFixFlat<CTeacher>(10);
CleanupStack::PushL(tecList);
rootStream.OpenLC(
rootStream>>*dictionary;
CleanupStack::PopAndDestroy();
TStreamId tid = dictionary->At(TUid::Uid(KTeachDataStreamId));
RStoreReadStream readStuStream;
readStuStream.OpenLC(*store,sid);
TInt32 numberOfStus;
readStuStream>>numberOfStus;
for (TInt i=0;i<numberOfStus;i++)
{
CStudent* stu = CStudent::NewL(readStuStream);
CleanupStack::PushL(stu);
stuList->AppendL(*stu);
CleanupStack::Pop();
}
CleanupStack::PopAndDestroy();
for (i=0;i<numberOfStus;i++)
{
(*stuList)[i].Display();
}
RStoreReadStream readTecStream;
readTecStream.OpenLC(*store,tid);
TInt32 numberOfTec;
readTecStream>>numberOfTec;
{
CTeacher* tec=CTeacher::NewL(readTecStream);
CleanupStack::PushL(tec);
tecList->AppendL(*tec);
CleanupStack::Pop();
}
CleanupStack::PopAndDestroy(); // readTechStream;
_LIT(kfmt2,"list tech:\n");
console->Printf(kfmt2);
for (i=0;i<numberOfTec;i++)
{
(*tecList)[i].Display();
}
delete dictionary;
CleanupStack::PopAndDestroy(store);
CleanupStack::PopAndDestroy(2); // array list
}
// Local Functions
LOCAL_C void MainL(const TDesC& aArgs)
{
//
// add your program code here, example code below
//
//console->Write(_L("Hello, world!\n"));
RFs iFs;//文件会话
User::LeaveIfError(iFs.Connect());//connect to file server
_LIT(KFileName,"c:\\stuList1.txt");
TBuf<20> FileName(KFileName);
//StoreL(iFs,FileName);
RestoreL(iFs,FileName);
iFs.Close();
console->Printf(_L("Command line args: \"%S\"\n"), &aArgs);
}
简单总结一下:
CDirectFileStore 去打开或创建一个文件,通过 RStoreWriteStream 来写入数据,对于多个流来说,要通过CStreamDictionary去保存这些流对像然后把 CStreamDictionary 保存成 CDirectFileStore 的 root(),RStoreReadStream 要先通过Root得到 CStreamDictionary ,再找到 RStoreReadStream进行读取数据。
安平2009@原创
qi_jianzhou@126.com