symbian os:分块儿读取文本中汉字被截断的问题(文字半角问题)

来源:互联网 发布:二叉树的层序遍历算法 编辑:程序博客网 时间:2024/05/16 00:27

笔者希望可以从文本中,将汉字读取出来,然后分段写到Editor内

无奈会出现文字半角问题。

汉字为2个字节,但是我们的RFile处理的都是8bit的流。使用RFile还有一个很重要的原因那就是。它提供了一个seek()很好用。

查了很多帖子。就目前的一个解决方案提出来。

直接上代码吧:

op_num++;             _LIT(path,"C:\\ebooks.txt");             TInt zero=0;             TText8 string[321];              TBuf8<320> rText;                          file.Seek(ESeekStart,currentPosition);             file.Read(rText);                          Mem::Copy(string,rText.Ptr(),rText.Size());             string[rText.Size()]='\0';                          HBufC16* msg = ToUnicodeConvertL(string);                                                  SetEditorText(*msg);            iEditor->DrawDeferred();                        delete msg;                        TInt iPos=PreToUnicodeConvertL(string);            currentPosition=currentPosition+320-iPos;
HBufC16* CPlainTextEditorContainer::ToUnicodeConvertL(TText8* aOrigin)  { CCnvCharacterSetConverter* converter=CCnvCharacterSetConverter::NewLC();    //RFs fSession;    //需要打开文件服务器   //User::LeaveIfError(fSession.Connect());    //判断传入的源字符串是否GBK\GB2123码   if(converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk,CCoeEnv::Static()->FsSession())!=CCnvCharacterSetConverter::EAvailable)    {    //如果不是GBK\GBK2123码就退出   //fSessoin.Close();    CleanupStack::Pop(converter);    delete converter; User::Leave(KErrNotSupported);    }    TText8* str = aOrigin;    TInt state=CCnvCharacterSetConverter::KStateDefault;       TPtrC8 source( str ); HBufC* iInfoText = HBufC::NewL( source.Length() );     TPtr16 ptr = iInfoText->Des();       if(CCnvCharacterSetConverter::EErrorIllFormedInput == converter->ConvertToUnicode(ptr, source, state))                                                              User::Leave(KErrArgument);     //转换完成并清除转换器            CleanupStack::PopAndDestroy();            return iInfoText;  }TInt CPlainTextEditorContainer::PreToUnicodeConvertL(TText8* aOrigin)  { CCnvCharacterSetConverter* converter=CCnvCharacterSetConverter::NewLC();    //RFs fSession;    //需要打开文件服务器   //User::LeaveIfError(fSession.Connect());    //判断传入的源字符串是否GBK\GB2123码   if(converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk,CCoeEnv::Static()->FsSession())!=CCnvCharacterSetConverter::EAvailable)    {    //如果不是GBK\GBK2123码就退出   //fSessoin.Close();    CleanupStack::Pop(converter);    delete converter; User::Leave(KErrNotSupported);    }    TText8* str = aOrigin;    TInt state=CCnvCharacterSetConverter::KStateDefault;       TPtrC8 source( str ); HBufC* iInfoText = HBufC::NewL( source.Length() );     TPtr16 ptr = iInfoText->Des();       TInt ipos=converter->ConvertToUnicode(ptr, source, state);                                                             CleanupStack::PopAndDestroy();            return ipos;  }


代码中有一个currentPostion。他记录了当前位置。这位置不是随便取的。它保证了转换过程中,流的开头肯定不会发生截断。

如果发生截断,那肯定是在流的最后。然后对下一个读取位置进行相应的调整即可。

是否发生截断,是利用了API:TInt ipos=converter->ConvertToUnicode(ptr, source, state);
这个API的解释很多帖子都有提到。这里不再赘述。


缺点及未解决的问题:

1:由于从开头读取文本时。currentPostion为0.就保证了流的开头不会有截断。然后往后顺序截取转换。调整后都可以保证

currentPostion流的开头不会截断。笔者试着从当前位置往左截取一段。按照同样的原理来转换。但是效果不理想。

2:不能解决随机读得问题。


如果知道汉字边界检测的方法。就好办了。在网上查了一些。好像不多见。先使用这个方案吧。以后有更好的。再换。