文件读写方案确定:读写模式选择问题
2010-07-12 12:43
363 查看
devdiv帖子收藏
提问金额: 1 可用分
如何使用RMutex
使用RMutex可以确保你的线程不会再同一时间试图改变同一个值。RMutex.Wait()提供一个锁机制,用RMutex.Signal()才能打开。
头文件
在线程间共享iShareValue变量
class CShared : CBase
{
public:
static CShared* NewL();
virtual ~CShared();
private:
CShared();
public:
RMutex iMutex;
// Shared data
TInt iSharedValue;
};
源文件
生成一个线程,并将CShared数据指针传入:
// Create shared data
iSharedData = CShared::NewL();
// Create threads
iMyThread = CMyThread::NewL(*this);
iMyThread->SetShared(iSharedData);
iMyThread2 = CMyThread::NewL(*this);
iMyThread2->SetShared(iSharedData);
线程调用RMutex::Wait()开始睡眠等待
TInt CMyThread::ThreadFunction(TAny* aParams)
{
// Add cleanup stack support.
CTrapCleanup* cleanupStack = CTrapCleanup::New();
// Get pointer to thread host
CMyThread* host = (CMyThread*)aParams;
TRAPD(err,
// Add support for active objects
CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(activeScheduler);
CActiveScheduler::Install(activeScheduler);
// Create and start CPeriodic class that is executed in this thread
CPeriodic* periodic = CPeriodic::NewL(CActive::EPriorityLow);
CleanupStack::PushL(periodic);
periodic->Start(host->Interval(),host->Interval(),
TCallBack(host->PeriodicTick, host));
// NOTE: When adding CActiveScheduler support for threads we have to
// add at least one active object in it or it fails on
// CActiveScheduler::Start().
// CPeriodic is derived from CActive active object so that is good for
// this example.
// --> Thread execution starts
CActiveScheduler::Start();
// --> Thread execution ends (waiting for CActiveScheduler::Stop())
CleanupStack::PopAndDestroy(periodic);
CleanupStack::PopAndDestroy(activeScheduler);
);
host->ThreadExecuted(err);
delete cleanupStack;
return KErrNone;
}
在睡眠后调用PeriodicTick()改变共享数据对象的值,并用RMutex::Signal()释放
TInt CMyThread::PeriodicTick(TAny* aObject)
{
CMyThread* mythread = (CMyThread*)aObject;
if (mythread)
{
// ---> Acquire the lock
mythread->Shared()->iMutex.Wait();
// Change shared data value
mythread->Shared()->iSharedValue++;
// ---> Release the lock
mythread->Shared()->iMutex.Signal();
// Thread is executed once so time to stop it
CActiveScheduler::Stop();
// After this execution continues from CActiveScheduler::Start()
}
// Does not continue again
// Note: Does not work with this CPeriodic class
return EFalse;
}
完成CShared数据
CShared* CShared::NewL()
{
CShared* self = new (ELeave) CShared();
return self;
}
CShared::CShared()
{
iMutex.CreateLocal();
}
CShared::~CShared()
{
iMutex.Close();
}
NOTE
线程依次去改变共享对象的值,如果调用RMutex::Wait()后另一个线程就要等待,在RMutex::Signal()之后才继续。
Retrieved from http://wiki.forum.nokia.com/index.php/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8RMutex
http://www.devdiv.net/thread-16357-1-1.html
文件服务器会话(File Server Session)
提问金额: 1 可用分
1.由于频繁写入文件,同时要读入该文件 很容易造成不同步的情况,,寻求大家解决 方案 要求如下: 1.RFileWriteStream时,该文件锁定,RFileReadStream只有等RFileWriteStream写完成之后才能读入 2.读文件是通过活动对象来检测写文件有变化,才开始读,如果该 文件锁定,需等待完成之后才能再读入 不知道该用哪种模式? 读该文件: InternalizeSettingsDataL() { RFs& fs = iEikonEnv->FsSession(); RFileReadStream readStream; TInt error = readStream.Open(fs, iSettingsFile, EFileRead); TInt internalizationError = KErrNone; // if file existed, try to read settings. if (error == KErrNone) { TRAP(internalizationError, iData->LoadL(readStream);) } readStream.Release(); // reading failed, settings file might be corrupted. if (internalizationError != KErrNone) { User::LeaveIfError(fs.Delete(iSettingsFile)); } } 复制代码 写该 文件: ExternalizeSettingsDataL() const { RFs& fs = iEikonEnv->FsSession(); RFileWriteStream writeStream; TInt error = writeStream.Open(fs, iSettingsFile, EFileWrite); // setting file did not exist, create one. if (error != KErrNone) { [b][color=Blue]//这里用EFileWrite|EFileShareExclusive 好像不行。。。。。。[/color][/b] User::LeaveIfError(writeStream.Create(fs, iSettingsFile, EFileWrite)); // } writeStream.PushL(); iData->SaveL(writeStream); writeStream.CommitL(); writeStream.Pop(); writeStream.Release(); } 记得其他语言都有写文件独占锁定的功能,,symbian的多的看的着痛。。。。。。。。。。。。。 有经验的同学指点一二 回复: 如果是当进程可以使用RMutex达到你的要求,用一个C类包装文件的读写, 伪代码如下: void ReadFileL( ) { iMutex.Wait();//iMutex是RMutex //read file... iReadStream.Close;//关闭文件 iMutex.Signal(); } void WriteStreamL() { iMutex.Wait();//iMutex是RMutex //write file... iWriteStream.Close;//关闭文件 iMutex.Signal(); } 如果是多进程,则使用CS架构,将这C类放在Server端就行了. |
使用RMutex可以确保你的线程不会再同一时间试图改变同一个值。RMutex.Wait()提供一个锁机制,用RMutex.Signal()才能打开。
头文件
在线程间共享iShareValue变量
class CShared : CBase
{
public:
static CShared* NewL();
virtual ~CShared();
private:
CShared();
public:
RMutex iMutex;
// Shared data
TInt iSharedValue;
};
源文件
生成一个线程,并将CShared数据指针传入:
// Create shared data
iSharedData = CShared::NewL();
// Create threads
iMyThread = CMyThread::NewL(*this);
iMyThread->SetShared(iSharedData);
iMyThread2 = CMyThread::NewL(*this);
iMyThread2->SetShared(iSharedData);
线程调用RMutex::Wait()开始睡眠等待
TInt CMyThread::ThreadFunction(TAny* aParams)
{
// Add cleanup stack support.
CTrapCleanup* cleanupStack = CTrapCleanup::New();
// Get pointer to thread host
CMyThread* host = (CMyThread*)aParams;
TRAPD(err,
// Add support for active objects
CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(activeScheduler);
CActiveScheduler::Install(activeScheduler);
// Create and start CPeriodic class that is executed in this thread
CPeriodic* periodic = CPeriodic::NewL(CActive::EPriorityLow);
CleanupStack::PushL(periodic);
periodic->Start(host->Interval(),host->Interval(),
TCallBack(host->PeriodicTick, host));
// NOTE: When adding CActiveScheduler support for threads we have to
// add at least one active object in it or it fails on
// CActiveScheduler::Start().
// CPeriodic is derived from CActive active object so that is good for
// this example.
// --> Thread execution starts
CActiveScheduler::Start();
// --> Thread execution ends (waiting for CActiveScheduler::Stop())
CleanupStack::PopAndDestroy(periodic);
CleanupStack::PopAndDestroy(activeScheduler);
);
host->ThreadExecuted(err);
delete cleanupStack;
return KErrNone;
}
在睡眠后调用PeriodicTick()改变共享数据对象的值,并用RMutex::Signal()释放
TInt CMyThread::PeriodicTick(TAny* aObject)
{
CMyThread* mythread = (CMyThread*)aObject;
if (mythread)
{
// ---> Acquire the lock
mythread->Shared()->iMutex.Wait();
// Change shared data value
mythread->Shared()->iSharedValue++;
// ---> Release the lock
mythread->Shared()->iMutex.Signal();
// Thread is executed once so time to stop it
CActiveScheduler::Stop();
// After this execution continues from CActiveScheduler::Start()
}
// Does not continue again
// Note: Does not work with this CPeriodic class
return EFalse;
}
完成CShared数据
CShared* CShared::NewL()
{
CShared* self = new (ELeave) CShared();
return self;
}
CShared::CShared()
{
iMutex.CreateLocal();
}
CShared::~CShared()
{
iMutex.Close();
}
NOTE
线程依次去改变共享对象的值,如果调用RMutex::Wait()后另一个线程就要等待,在RMutex::Signal()之后才继续。
Retrieved from http://wiki.forum.nokia.com/index.php/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8RMutex
http://www.devdiv.net/thread-16357-1-1.html
文件服务器会话(File Server Session)
DevDiv Symbian技巧大全系列之文件服务器会话(File Server Session)
1、文件服务器会话(File Server Session) Symbian中的文件操作离不开文件服务器会话api——RFs。文件服务器运行于EFile.exe中,RFs api提供了通往文件服务器的“通道”,通过RFs我们可以执行各种文件操作。 2、获取File Server Session的常用方法 1)使用RFs的Connect()方法: RFs aFSSession; User::LeaveIfError(aFSSession.Connect()); // 可以使用aFSSession // ...... // 关闭file server session,释放相关资源 aFSSession.Close(); 2)使用CCoeEnv: GUI程序拥有控件环境(CCoeEnv),CCoeEnv由app framework构造,它持有一个File Server Session,并提供一个FsSession()方法获取FSS: RFs& aFSSession = iCoeEnv->FsSession(); 在UI框架中,CEikApplication、CCoeAppUi和CCoeControl都拥有iCoeEnv成员,所以在这些类中都可以使用上面的代码获取FSS。 3)使用CCoeEnv::Static(): 在GUI程序中,如果你想在一些自己写的一些类中获取FSS,可以使用下列方法: RFs& aFSSession = CCoeEnv::Static()->FsSession(); 4)使用CEikonEnv: CEikonEnv继承自CCoeEnv,使用它来获取FSS与使用CCoeEnv是一样的。 RFs& aFSSession = iEikonEnv->FsSession(); 或者: RFs& aFSSession = CEikonEnv::Static()->FsSession(); 说明:iEikonEnv定义于eikdef.h中 #define iEikonEnv (STATIC_CAST(CEikonEnv*,iCoeEnv)) 常用文件操作 1、写入二进制数据 DevDiv Symbian技巧大全系列之常用文件操作
symbian中二进制数据通常存储在8位描述符中,如TBuf8、HBufC8。 下面的函数演示了如何向一个文件写入二进制数据: static void WriteDesC8ToFileL(const TDesC& aFileName, const TDesC8& aBinaryData) { RFile aFile; User::LeaveIfError(aFile.Replace(CCoeEnv::Static()->FsSession(), aFileName, EFileWrite)); CleanupClosePushL(aFile); User::LeaveIfError(aFile.Write(aBinaryData)); // It will be release the resource of file // DO NOT Close AGAIN CleanupStack::PopAndDestroy(&aFile); }、 2、读出二进制数据 本帖隐藏的内容需要回复才可以浏览static void ReadDesC8FromFileL(const TDesC& aFileName, TDes8& aBuffer){ RFile aFile; User::LeaveIfError(aFile.Open(CCoeEnv::Static()->FsSession(), aFileName, EFileRead)); CleanupClosePushL(aFile); User::LeaveIfError(aFile.Read(aBuffer)); CleanupStack::PopAndDestroy(&aFile); } 3、从文本文件读取数据 本帖隐藏的内容需要回复才可以浏览多行的文本文件一般都由EOL分隔符来分隔每一行的数据。Symbian中的分隔符是LF(0x0A)。Symbian的文本文件通常都保存为Unicode格式。读写文本文件的常用api是TFileText,由于文本文件通常都为Unicode,所以TFileText api使用16位描述符作为参数。下面的函数演示了如何读取一个文本文件: static void ReadTextFileL(const TDesC& aFileName, TDes& aBuffer) { RFile aFile; User::LeaveIfError(aFile.Open(CCoeEnv::Static()->FsSession(), aFileName, EFileRead | EFileStreamText)); CleanupClosePushL(aFile); // create a TFileText and points it to file TFileText aFileText; aFileText.Set(aFile); TBuf<256> buffer; TInt errCode = KErrNone; while (errCode != KErrEof) { errCode = aFileText.Read(buffer); if (errCode == KErrNone) { aBuffer.Append(buffer); } } CleanupStack::PopAndDestroy(&aFile); } 使用TFileText可以读取换行符为CR LF(0x0D 0x0A)或LF(0x0A)的Unicode文件(包含BOM(Byte-Order Mark)的也可以)。另外注意不要使用TFileText来读取非Unicode文件,否则将会出现一些垃圾字符。 注意事项: 1、在Symbian OS V9之后(S60 3rd之后),系统中有一些目录是受保护的,读写这些目录必须具有相应的能力,比如向Resource目录写数据必须具有TCB能力才行。当你在文件操作是遇到-46错误,就要检查一下你所操作的目录是否需要特殊能力。2、使用RFile api时要特别关注api的返回值,它表示了文件操作是否正确完成,若发生错误,程序应该做一些错误处理。以下是一个简单的范例: _LIT16(KFileName, "C://Data//WantToWrite.ini"); _LIT8(KWriteContent, "DevDiv Test"); TInt errCode = 0; TRAP(errCode, WriteDesC8ToFileL(KFileName, KWriteContent)); if (errCode == KErrPathNotFound) { // 路径不存在,创建路径并重试 // 或者弹出错误提示告知用户,具体错误处理需根据需求或具体情况确定 } |
相关文章推荐
- 优化读取的异步文件过多问题(方案:对于已经处理过的文件可以选择移除到备份文件夹下,避免处理前遍历文件过多)
- c++ 文件操作二进制模式的读写问题
- 解决Unicode模式读写文件错误问题
- 多个地方同时向一个文件读写的互斥问题解决方案
- 【C++】小心使用文件读写模式:回车('\r') 换行('\n')问题的一次纠结经历
- 解决多线程同时读写一个文件的问题
- 文件读写的问题
- WinCE下用C库函数读写文件的问题
- 利用C#进行文件读写的方法选择总结
- 大数据架构和模式(五)——对大数据问题应用解决方案模式并选择实现它的产品
- [C#]解决读写包含汉字的txt文件时乱码的问题
- .NET:关于byte数组在用StreamWriter文件写出后出现多余字符的解决方法及VS方案文件图标显示问题
- PHP解决多进程同时读写一个文件的问题
- 文件内存映射mmap解决大文件快速读写问题和进程间共享内存
- 曾经被问到的一个问题:大文件该怎么读写
- android中选择文件,部分手机找不到文件路径问题的解决
- 大数据架构和模式(五)——对大数据问题应用解决方案模式并选择实现它的产品
- linux下给php安装pdo_mysql和zlib以及测试模式的选择(禅道安装过程中遇到的问题)
- C语言文件读写操作中缓冲区问题和setbuf函数详解
- 读写csv文件的问题