文件流与存储流

 

文件流与存储流

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()提交

下面是练习的代码,根据上面说的再来看代码就能更清楚的理解了

#include  " FileStore.h "
#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 *  NewL(RReadStream &  aStream);
    
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
*  CStudent::NewL( TDesC &  aName,TInt32 aNo,TInt32 aScore )
{
    CStudent
*  self  =  CStudent::NewLC(aName,aNo,aScore);
    CleanupStack::Pop();
    
return  self;
}

CStudent
*  CStudent::NewL( RReadStream &  aStream )
{
    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
*  CStudent::NewLC( RReadStream &  aStream )
{
    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();
}

CStudent::CStudent()
{
    
}

CStudent::CStudent( TInt32 aNo,TInt32 aScore )
{
    iNo 
=  aNo;
    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 *  NewL(RReadStream &  aStream);
    
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
*  CTeacher::NewL( TDesC &  aName,TInt32 aNo,TInt32 aAge )
{
    CTeacher
*  self  =  CTeacher::NewLC(aName,aNo,aAge);
    CleanupStack::Pop();
    
return  self;
}

CTeacher
*  CTeacher::NewL( RReadStream &  aStream )
{
    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
*  CTeacher::NewLC( RReadStream &  aStream )
{
    CTeacher
*  self  =   new (ELeave)CTeacher();
    CleanupStack::PushL(self);
    self
-> InternalizeL(aStream);
    
return  self;
}
CTeacher::
~ CTeacher()
{
    delete iName;
    iName 
=  NULL;

}

CTeacher::CTeacher()
{
    
}

CTeacher::CTeacher( TInt32 aNo,TInt32 aAge )
{
    iNo 
=  aNo;
    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 >  name1(KName1);
    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
< CStudent >*  stuList =   new (ELeave)CArrayFixFlat < CStudent > ( 4 );
    CArrayFixFlat
< CTeacher >*  tecList =   new (ELeave)CArrayFixFlat < CTeacher > ( 4 );

    stuList
-> AppendL( * stu1);
    stuList
-> AppendL( * stu2);
    tecList
-> AppendL( * tec1);
    tecList
-> AppendL( * tec2);

    CFileStore
*  store = CDirectFileStore::ReplaceLC(aFs,aFileName,EFileWrite);
    store
-> SetTypeL(TUidType(store -> Layout()));

    CStreamDictionary
*  dictionary  =  CStreamDictionary::NewLC();

    RStoreWriteStream stuStream;  
//  写入流
    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();

    RStoreWriteStream tecStream;
    TStreamId tId 
=  tecStream.CreateLC( * store);
    TInt32 numberOfTechers 
=  tecList -> Count();
    tecStream
<< numberOfTechers;
    
for  (i = 0 ;i < numberOfTechers;i ++ )
    {
        (
* tecList)[i].ExternalizeL(tecStream);
    }
    tecStream.CommitL();
    CleanupStack::PopAndDestroy();

    dictionary
-> AssignL(TUid::Uid(KStuDataStreamId),sid);
    dictionary
-> AssignL(TUid::Uid(KTeachDataStreamId),tId);

    RStoreWriteStream root;      
//  根流
    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);

    CFileStore
*  store  =  CDirectFileStore::OpenLC(aFs,aFileName,EFileRead);

    CStreamDictionary
*  dictionary  =  CStreamDictionary::NewL();

    RStoreReadStream rootStream;
    rootStream.OpenLC(
* store,store -> Root());
    rootStream
>>* dictionary;
    CleanupStack::PopAndDestroy();

    TStreamId sid 
=  dictionary -> At(TUid::Uid(KStuDataStreamId));
    TStreamId tid 
=  dictionary -> At(TUid::Uid(KTeachDataStreamId));

    
// CleanupStack::PopAndDestroy();  //  dict

    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();

    _LIT(kfmt,
" list students:\n " );
    
for  (i = 0 ;i < numberOfStus;i ++ )
    {
        (
* stuList)[i].Display();
    }

    
//  读出教师数据
    RStoreReadStream readTecStream;
    readTecStream.OpenLC(
* store,tid);
    TInt32 numberOfTec;
    readTecStream
>> numberOfTec;

    
for  (i = 0 ;i < numberOfTec;i ++ )
    {
        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

转载于:https://www.cnblogs.com/zziss/archive/2010/01/22/1653767.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值