您的位置:首页 > 其它

Symbian 文件读写实例

2009-08-27 18:30 337 查看
说明:异步文件读写的实例 里面有活动对象的应用和文件系统的应用

要运行本例要在C:/Symbian/9.1/S60_3rd_MR/Epoc32/winscw/c/examples/FileAsyReadWrite目录下建立文件GoldMedal 文件没有扩展名 其中的内容是:

Weightlifting LU Yong
Weightlifting CHEN Xiexia
Weightlifting CHEN Yanqing
Rowing TANG Bin,JIN Ziwei,Xi Aihua,ZHANG Yangyang
Weightlifting LIU Chunhong
Weightlifting CAO Lei
Sailing YIN Jian

在carbide下面建立项目Basic console application(EXE) 的项目 FileAsyReadWrite

下面是主类

FileAsyReadWrite.h和FileAsyReadWrite.cpp

其中:

FileAsyReadWrite.h如下:

#ifndef __FILEASYREADWRITE_H__
#define __FILEASYREADWRITE_H__

//  Include Files

#include <e32base.h>

//  Function Prototypes

GLDEF_C TInt E32Main();

#endif  // __FILEASYREADWRITE_H__


FileAsyReadWrite.cpp如下:

#include "FileAsyReadWrite.h"
#include <e32base.h>
#include <e32std.h>
#include <e32cons.h>			// Console
#include "FileReadWrite.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
//  Local Functions

LOCAL_C void MainL()
{
_LIT(KFileName,"C://examples//FileAsyReadWrite//GoldMedal");
CFileReadWrite* fr=CFileReadWrite::NewL(*console,KFileName);
//这个是定义自己的类(传递输出对象和文件名) 通过上面的类打开了文件服务器和时间服务器 他们已经准备好了要做动作
fr->DoRead();
CActiveScheduler::Start();
delete fr;
console->Write(_L("Read Complete!/n"));
}

LOCAL_C void DoStartL()
{
// Create active scheduler (to run active objects)
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);

MainL();

// Delete active scheduler
CleanupStack::PopAndDestroy(scheduler);
}

GLDEF_C TInt E32Main()
{
// Create cleanup stack
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();

// Create output console
TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(
KConsFullScreen, KConsFullScreen)));
if (createError)
return createError;

// Run application code inside TRAP harness, wait keypress when terminated
TRAPD(mainError, DoStartL());
if (mainError)
console->Printf(KTextFailed, mainError);
console->Printf(KTextPressAnyKey);
console->Getch();

delete console;
delete cleanup;
__UHEAP_MARKEND;
return KErrNone;
}


下面建立symbian类 FileReadWrite

其中FileReadWrite.h如下:

#ifndef FILEREADWRITE_H
#define FILEREADWRITE_H

#include <e32base.h>	// For CActive, link against: euser.lib
#include <e32std.h>		// For RTimer, link against: euser.lib
#include <f32file.h>	//文件读取的头文件
#include <e32cons.h>
#include <BADESCA.h>    //CDesCArrayFlat

static const TInt KFileNameLength(100);
static const TInt KReadSizePerTime(50);

class CFileReadWrite : public CActive
{
public:
// Cancel and destroy
~CFileReadWrite();

// Two-phased constructor.
static CFileReadWrite* NewL(CConsoleBase& aConsole,const TDesC& aFileName);

// Two-phased constructor.
static CFileReadWrite* NewLC(CConsoleBase& aConsole,const TDesC& aFileName);

public:
//封装了异步读取函数
void DoRead();
//当读取结束后 创建一个文件 保存读取结果
void CreateNewFileL();
//封装了异步写入函数
void DoWrite();
//封装了异步延时函数
void DoTimeDelay();//

//
// New functions
// Function for making the initial request
void StartL(TTimeIntervalMicroSeconds32 aDelay);

private:
// C++ constructor
CFileReadWrite(CConsoleBase& aConsole,const TDesC& aFileName);

//每读取一行后 将该数据保存到数组并且打印到控制台
void ShowNewlineBuf(TInt aPos);
// Second-phase constructor
void ConstructL();

private:
// From CActive
// Handle completion
void RunL();

// How to cancel me
void DoCancel();

// Override to handle leaves from RunL(). Default implementation causes
// the active scheduler to panic.
TInt RunError(TInt aError);

private:
enum TFileReadWriteState
{
EUninitialized, // Uninitialized
EInitialized, // Initalized
EError
// Error condition
};
enum TAOStatus
{
EReadFile,	//读取
ETimeDelay, //延时
EWriteFile	//写入
};
private:
TInt iState; // State of the active object
RTimer iTimer; // Provides async timing service

RFile iFile;
RFs iFileServer;//访问文件服务器的句柄 因为需要资源 要求数量少
TBuf<KFileNameLength> iFileName;//储存文件名的描述符
TBuf8<KReadSizePerTime> iBufContainer;//文件中的数据读取存储的地方
HBufC* iOnelineBuf;
TInt iFilePos;
CConsoleBase& iConsole;
TBool isTimeDelay;
TAOStatus iAOStatus;
CDesCArrayFlat* iBufArray;
TInt iWritePos;
TBuf<KFileNameLength> iCopyFileName;

};

#endif // FILEREADWRITE_H


其中FileReadWrite.cpp如下:
#include "FileReadWrite.h"
#include <e32cmn.h>

static const TInt KTimeDelay(500*1000);

_LIT(KNewline, "/n");
_LIT(KCopyFileName, "copy");
_LIT(KOpenFile, "Open a file/n/n");
_LIT(KReadingFile, "Reading.../n/n");
_LIT(KCreatNewFile,"Create a new file%S in %S./n/n");
_LIT(KWriting,"Writing datas to %S.../n/n");
_LIT(KWriteComplete, "Write complete!/n/n");

CFileReadWrite* CFileReadWrite::NewLC(CConsoleBase& aConsole,const TDesC& aFileName)
{
CFileReadWrite* self = new (ELeave) CFileReadWrite(aConsole,aFileName);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}

CFileReadWrite* CFileReadWrite::NewL(CConsoleBase& aConsole,const TDesC& aFileName)
{
CFileReadWrite* self = CFileReadWrite::NewLC(aConsole,aFileName);
CleanupStack::Pop(); // self;
return self;
}

CFileReadWrite::~CFileReadWrite()
{
Cancel(); // Cancel any request, if outstanding
iTimer.Close(); // Destroy the RTimer object
// Delete instance variables if any
delete iOnelineBuf;
delete iBufArray;
}

void CFileReadWrite::StartL(TTimeIntervalMicroSeconds32 aDelay)
{
Cancel(); // Cancel any request, just to be sure
iState = EUninitialized;
iTimer.After(iStatus, aDelay); // Set for later
SetActive(); // Tell scheduler a request is active
}

TInt CFileReadWrite::RunError(TInt aError)
{
return aError;
}

void CFileReadWrite::DoRead()
{
//将活动对象置为EReadFile
iAOStatus=EReadFile;//初始化自定义状态
//从文件头开始偏移iFilePos位置
iFile.Seek(ESeekStart,iFilePos);//这里iFilePos==0 这里设置文件当前的读取位置  从文件头开始偏移0个位置开始读
//从iFilePos 位置开始读取头文件把iBufContainer填满
iFile.Read(iBufContainer,iBufContainer.MaxSize(),iStatus);//开始读文件 把iBufContainer读慢 就是读取50个字符
SetActive();
}

void CFileReadWrite::CreateNewFileL()
{
TParse fileParse;//创建一个文件解析对象
//把C://examples//FileAsyRead//GoldMedal 文件名付给TParse
fileParse.Set(iFileName,NULL,NULL);//构建和操作文件名

//获得文件名:GoldMedal,存入copyFileName
TPtrC fileName=fileParse.Name();// GoldMedal
RBuf copyFileName;
copyFileName.CleanupClosePushL();
copyFileName.Create(fileName.Length()+KCopyFileName().Length());
copyFileName.Append(fileName);

//在文件名GoldMedal 后面附加一个copy 获得新文件名GoldMedalcopy
copyFileName.Append(KCopyFileName);
iCopyFileName.Copy(copyFileName);

//得到驱动器+目录:“c://examples//FileAsyRead//”
TPtrC driveAndPath=fileParse.DriveAndPath();

//在“驱动器+目录”后附加新文件名,得到新文件路径名:c://examples//fileAsyRead//GoldMedalcopy,
//存入 copyFileFullName
RBuf copyFileFullName;
copyFileFullName.CleanupClosePushL();
copyFileFullName.Create(driveAndPath.Length()+fileName.Length()+KCopyFileName().Length());
copyFileFullName.Append(driveAndPath);
copyFileFullName.Append(copyFileName);

//先关闭原来的GoldMedal 的文件会话
iFile.Close();

//创建GoldMedalcopy 的新文件会话   Replace 如果指定文件存在则替换现有文件并打开 如果不存在就创建一个
User::LeaveIfError(iFile.Replace(iFileServer,copyFileFullName,EFileWrite));
iConsole.Printf(KCreatNewFile,&iCopyFileName,&driveAndPath);

//销毁俩个BUf
CleanupStack::PopAndDestroy(2,©FileName);
//复位iFilePos
iFilePos=0;
}

void CFileReadWrite::DoWrite()
{
//将活动对象状态置为EWriteFile
iAOStatus=EWriteFile;

//从文件头开始查找到文件的末尾位置
TInt start=0;
iFile.Seek(ESeekEnd,start);

//构造一个指向16位描述符的8位指针描述符
TPtrC16 ptrcbuf16=(*iBufArray)[iWritePos];
TPtrC8 ptrcBuf8((TUint8*)ptrcbuf16.Ptr(),ptrcbuf16.Size());

//从文件末尾写入hBuf8
iFile.Write(ptrcBuf8,iStatus);
SetActive();

iWritePos++;
}

void CFileReadWrite::DoTimeDelay()
{
//将活动对象状态置为 ETimeDelay
iAOStatus=ETimeDelay;
iTimer.After(iStatus,KTimeDelay);
SetActive();
}

void CFileReadWrite::ConstructL()
{
//连接文件服务器 RFs类的方法 连接文件服务器
User::LeaveIfError(iFileServer.Connect());

//按照指定的文件名以只读的方式打开文件 创建一个指向这个文件的文件会话(RFs,文件名,打开方式(只读))
User::LeaveIfError(iFile.Open(iFileServer,iFileName,EFileRead));//

//打开定时器 iTimer是定时器类RTimer(打开定时器)
User::LeaveIfError(iTimer.CreateLocal());

//创建描述符数组,用于保存读出的字符串
iBufArray=new (ELeave) CDesCArrayFlat(5);//swb

//打印控制台信息
iConsole.Write(KOpenFile);//Open a file
iConsole.Write(KReadingFile);//Reading...
}

CFileReadWrite::CFileReadWrite(CConsoleBase& aConsole,const TDesC& aFileName):
CActive(CActive::EPriorityStandard),iFileName(aFileName),iFilePos(0),iConsole(aConsole),iWritePos(0)
{
CActiveScheduler::Add(this);
}

void CFileReadWrite::ShowNewlineBuf(TInt aPos)//那个位置+2
{
//在重新分配HBufC成员指针之前,先德勒特 再赋为NULL
delete iOnelineBuf;
iOnelineBuf=NULL;

//重新分配HBufC成员
iOnelineBuf=HBufC::NewLC(aPos+1);
TPtr pNewline=iOnelineBuf->Des();

//将iBufContainer 里面的16位描述符 保存到8位描述符iOnelineBuf
pNewline.Copy(iBufContainer.Left(aPos));

//添加字符到描述符数组里
iBufArray->AppendL(pNewline);

//改变文件读取位置标记
iFilePos+=aPos;

//打印控制台信息
iConsole.Write(*iOnelineBuf);
iConsole.Write(KNewline);

//从清理栈中弹出iOnelineBuf
CleanupStack::Pop();
}

void CFileReadWrite::RunL()
{
if(iStatus==KErrNone)//iStatus是TRequestStatus的状态监视器  如果一切正常 就是KErrNone 这里是文件读取成功了
{
switch(iAOStatus)
{
case EReadFile:	//如果是读取的话 那么看下面
{
//查找iBufContainer中是否有分割符‘;’
TChar newline('/r');//回车键
TInt pos=iBufContainer.Locate(newline);//定位指定字符的位置;
if(pos!=KErrNotFound)//KErrNotFound=-1;如果有/r
{
//如果分割符中有‘,’ 则在控制台中显示该行数据
ShowNewlineBuf(pos+2);
}
else 	//如果没有分割符',' 分析是否读取到了文件尾
{//如果没有读取到文件尾 则继续读取
if(iBufContainer.Length()>0)
{
iFilePos+=iBufContainer.Length();
DoRead();
break;//swb
}
else//读取到了文件尾
{
CreateNewFileL();
iConsole.Printf(KWriting,&iCopyFileName);
DoWrite();
break;
}
}
//每读到一行数据后,延时一段时间
DoTimeDelay();
}
break;
case ETimeDelay:
{
DoRead();
}
break;
case EWriteFile:
{
if(iWritePos<iBufArray->Count())
{
DoWrite();
}
else//如果到达iBufArray尾,停止活动对象调度器
{
iConsole.Write(KWriteComplete);
CActiveScheduler::Stop();
}
}
default:
break;
}
}
}

void CFileReadWrite::DoCancel()
{
iFile.Close();
iFileServer.Close();
iTimer.Close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: