使用RFile.Write写文本文件时,如果描述符中有UNICODE编码的汉字,直接写的话,文件里会是乱码;这时就需要进行转码。
我自己写了ConvertUnicodeToUtf8L函数来讲unicode字符转为utf8编码格式,只需调用此函数进行转码:
case EUserActionStringData:
{
HBufC* pString = (HBufC*)(item->GetData());
TPtrC16 ptrStr16 (pString->Des());
TBuf8<0x100> convertCache;
ConvertUnicodeToUtf8L(convertCache,ptrStr16);
dataCache.Append(convertCache);
break;
}
...
dataCache.Append(_L("/r/n"));
file.Write(dataCache);
ConvertUnicodeToUtf8L函数实现如下:
void CTTUserActionDataManager::ConvertUnicodeToUtf8L( TDes8& aDestBuf,const TDesC16& aSourceBuf )
{
TInt srcLen = aSourceBuf.Length();
TInt destMaxLen = aDestBuf.MaxLength();
if(srcLen <= 0 || destMaxLen < srcLen * 2)
{
return;
}
TInt state = CCnvCharacterSetConverter::KStateDefault;
if(CCnvCharacterSetConverter::EErrorIllFormedInput ==iUtf8Converter->ConvertFromUnicode(aDestBuf, aSourceBuf, state))
{
User::Leave(KErrArgument);
}
}
其中,iUtf8Converter 是一个CCnvCharacterSetConverter类型的成员变量指针,其创建放在类的ConstructL里面:
iUtf8Converter = CCnvCharacterSetConverter::NewL();
if(iUtf8Converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8, CCoeEnv::Static()->FsSession()) != CCnvCharacterSetConverter::EAvailable)
{
User::Leave(KErrNotSupported);
}
UFT8文件还要在其头部写入ROM信息,否则某些文本编辑器不能识别:
// utf8 byte order mark
TBuf8<0x50> utf8Buf;
TChar ch1(0xEF);
TChar ch2(0xBB);
TChar ch3(0xBF);
utf8Buf.Append(ch1);
utf8Buf.Append(ch2);
utf8Buf.Append(ch3);
file.Write(utf8Buf);