我需要逐行读取一个UTF-8文件,每一行包含一个单词和它的权重(一个数字)。所以我需要读取下一行,然后用分隔符(制表符)来分割一行并将其保存在内存中。
因此,
1)是否有一个库可以在Delphi中处理UTF-8文件(第三方库可能会有)?
2)函数是否能够与WideString一起正常工作?我使用PosEx。如果不能,请您提供一个用于处理WideStrings的第三方库链接?
WideString
。ASCII是UTF-8的子集,任何ASCII字符都保证不会干扰UTF-8中用于其他字符的特殊编码。数字字符0
到9
和制表符都是ASCII字符。WideString是一个UTF-16实现(与COM BSTR兼容),它不能存储UTF-8字符串,如果您分配了一个8位字符串,它将被转换为UTF-16。但是,除非您明确使用适当的转换函数,否则Delphi将使用当前代码页解释8位字符串。
UTF-8字符串可以存储在Delphi AnsiString中(Delphi 7中的默认字符串类型),但是字符串操作函数是为ANSI代码页设计的,而不是UTF-8。区别在于UTF-8是多字节字符集。但是,在前127个ANSI字符中,需要多个字节来编码给定的“字符”,而许多ANSI代码页(特别是欧洲语言的代码页)仅需要一个字节,仅编码255个“字符”(而UTF-8可以编码整个Unicode集)。
如果您只是寻找制表符字符AFAIK,则可以简单地使用AnsiString,但是您必须确保您可能需要查找的任何$80以上的字节不是多字节序列的一部分。如果您有更复杂的处理需求,可能更容易找到处理UTF-16字符串而不是UTF-8的库。正如Rob Kennedy所说,JCL是一个很好的起点,作为实现UTF字符串操作的免费库。
您可以通过TStringList的LoadFrom...()方法将文件直接读取为普通的TStringList,然后根据需要循环遍历列表。如果一次性将整个文件加载到内存中不是一个选项,则可以使用TFileStream打开文件,然后使用TStreamReader.ReadLine()方法逐行读取流。
如果您需要将给定的UTF-8序列解码为UTF-16进行处理,则建议直接使用Win32 API MultiByteToWideChar()函数,因为RTL的UTF8Decode()函数在旧版Delphi版本中存在破损的UTF-8实现(不确定D7是否有问题,但它在D6中肯定有问题)。
这两种加载方法的好处是它们都在D2009及更高版本中支持编码感知,这意味着如果您升级了,只需进行几个非常小的代码更改即可告诉RTL数据是UTF-8,并且它会自动将其解码为UTF-16,然后您的其余处理代码可以保持不变(假设您没有执行任何Ansi特定操作)。