(轉)S60系統的文件操作類

symbian平臺的封裝已經很利害了,但是對於文件的操作來說,
還是稍顯煩瑣.這裏我把自己封裝的一個用於常規文件操作的類貼出來,
目的是起到拋磚引玉的作用:

這個是頭文件了:
#include <s32file.h>
#include <e32std.h>
#include <e32def.h>
#define F_READ    0
#define F_WRITE   1
class CFileOp  
{
public:
        RFs iFs ;
        RFile iFile ;
        RFileWriteStream iFws ;
        RFileReadStream iFrs ;
        TBuf<100> iFileName ;
        TInt iSize ;
        TBool iIsOpened ;
        TInt iWhichStream ;
public:
        CFileOp();
        void SetFileName(const TDesC & filename) ;
        TInt GetSize() ;
        TBool Open(TInt openType) ;
        TInt Close() ;
        TInt Write(const TDesC8 & buf) ;
        TInt Write(const TUint8 * pbuf, TInt len) ;
        TInt Write(const TUint16 * pbuf, TInt len) ;
        TInt Read(TDes8 & buf, TInt len) ;
        TBool IsOpened() ;
        TBool GetFileName(TDes& file_name) ;
        TBool DeleteFile(const TDesC& file_name) ;
        TBool RenameFile(const TDesC& old_fname, TDes& new_fname) ;
        virtual ~CFileOp();
};


下面是cpp文件:
#include "FileOp.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFileOp::CFileOp()
{
        iSize = 0 ;
        iIsOpened = EFalse ;
}

CFileOp::~CFileOp()
{
}

void CFileOp::SetFileName(const TDesC & filename) {
        if(iFileName.Length() > 0) iFileName.SetLength(0) ;
        iFileName.Append(filename) ;
}

TBool CFileOp::Open(TInt openType) {
        TInt err = 0 ;        
        if(iIsOpened) Close() ;
        if(iFileName.Length() > 0) {
                User::LeaveIfError(iFs.Connect()) ;
                if(openType == F_WRITE) {
                        User::LeaveIfError(iFile.Replace(iFs, iFileName, EFileWrite));
                        iFws.Attach(iFile) ;
                } else {
                        // get the file size first
                        User::LeaveIfError(iFile.Open(iFs, iFileName, EFileRead)) ;
                        err = iFile.Size(iSize) ;
                        if(err != KErrNone)        {
                                iSize = -1 ;
                                return EFalse ;
                        }
                        iFrs.Attach(iFile) ;
                }
                iWhichStream = openType ;
                iIsOpened = ETrue ;
                return ETrue ;
        }
        return EFalse ;
}

TInt CFileOp::Close() {
        if(iIsOpened) {
                if(iWhichStream == F_READ) iFrs.Close() ;
                if(iWhichStream == F_WRITE) iFws.Close() ;
                iFs.Close() ;
        }
        iIsOpened = EFalse ;
        return 0 ;
}

TInt CFileOp::Write(const TDesC8 & buf) {
        iFws<<buf ;
        return buf.Length() ;
}

TInt CFileOp::Write(const TUint8* pbuf, TInt len) {
        TInt i ;
        for(i = 0 ; i < len ; i++) iFws<<(TUint8)pbuf ;
        return i ;
}

TInt CFileOp::Write(const TUint16* pbuf, TInt len) {
        TInt i ;
        for(i = 0 ; i < len ; i++) iFws<<(TUint16)pbuf ;
        return i ;
}

TInt CFileOp::Read(TDes8 & buf, TInt len) {
        buf.SetLength(0) ;
        iFrs.ReadL(buf, len) ;
        return buf.Length() ;
}

TInt CFileOp::GetSize() {
        return iSize ;
}

TBool CFileOp::IsOpened () {
        return iIsOpened ;
}

TBool CFileOp::GetFileName(TDes& file_name) {
        if(iFileName.Length() > 0) {
                file_name.Copy(iFileName) ;
                return ETrue ;  
        }
        return EFalse ;
}

TBool CFileOp::DeleteFile(const TDesC& file_name) {
        if(iIsOpened) Close() ;
        User::LeaveIfError(iFs.Connect()) ;
        iFs.Delete(file_name) ;
        iFs.Close() ;
        return ETrue ;
}

TBool CFileOp::RenameFile(const TDesC& old_fname, TDes& new_fname) {
        TInt error_code = KErrNone ;
        TParse parse ;
        if(iIsOpened) Close() ;
        User::LeaveIfError(iFs.Connect()) ;
        parse.Set(new_fname, NULL, NULL) ;
        if(parse.Ext().Length() <= 0) {
                // without file name extension we can't find the file type
                // so we have to add it
                parse.Set(old_fname, NULL, NULL) ;
                new_fname.Append(parse.Ext()) ;
        }
       
        error_code = iFs.Rename(old_fname, new_fname) ;
        iFs.Close() ;
        return (error_code == KErrNone) ? ETrue : EFalse ;
}
需要說明的是,Symbian S60的文件讀寫的時候,如果採用RFileWriteStream對象,
對於字符串寫入操作的時候,會莫名其妙的多寫入一個字節的數據.
很是讓人不爽,所以,我在這裏特別說明一下:
TInt CFileOp::Write(const TUint8* pbuf, TInt len) {
        TInt i ;
        for(i = 0 ; i < len ; i++) iFws<<(TUint8)pbuf ;   // <------這裏用了很土的方法
        return i ;
}
但是這樣可以確保不多寫入些東西, 甚至二進制文件都可以. 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章