文件流与存储流

文件流与存储流

 

文件流与存储流

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进行读取数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值