loadfromfile 上的 TStringlist 错误:目标多字节代码页中不存在 Unicode 字符的映射

TStringlist error on loadfromfile : No mapping for the Unicode character exists in the target multi-byte code page

我在尝试使用 TStringList.LoadFromFile 方法加载文件时遇到以下异常:

stringlist1.loadfromfile('c:\example.txt');

No mapping for the Unicode character exists in the target multi-byte code page

文件是Unicode,错误似乎与文件中存在的这个特殊字符有关。 example.txt文件只有一行,内容如下:

Ze 

文件包含这些字节:

EF BB BF 5A 65 20 ED A0 BC ED B7 AB ED A0 BC ED B7 AE

有什么解决方法吗?

作为第二个参数,您可以尝试添加编码(例如 UTF-8)。 我不确定这是否能解决您的问题,但可以。 希望对您有所帮助。

您的文件声称编码为 UTF-8,从前 3 个字节 EF BB BF 可以看出,它们是 UTF-8 BOM.

在 Delphi 2009+ 中,String 是 UTF-16 编码的 Unicode 字符串,因此 LoadFromFile() 会看到 BOM 并尝试将文件字节从 UTF-8 解码为Unicode,然后在内存中将该 Unicode 数据编码为 UTF-16。

但是,在 BOM 之后,接下来的 3 个字节 5A 65 20 是正确的 UTF-8,但文件的其余部分是 NOT 正确的 UTF-8 .这就是你得到例外的原因。

您显示的字符的正确字节序列应如下所示:

EF BB BF 5A 65 20 F0 9F 87 AB F0 9F 87 AE

但是您的文件包含这些字节:

EF BB BF 5A 65 20 ED A0 BC ED B7 AB ED A0 BC ED B7 AE

如您所见,正确文件中的字节序列 F0 9F 87 AB F0 9F 在您的错误文件中已 mis-encoded 为 ED A0 BC ED B7 AB ED A0 BC ED

当作为 UTF-8 处理时,好的文件解码为以下 Unicode 代码点序列:

U+005A LATIN CAPITAL LETTER Z
U+0065 LATIN SMALL LETTER E
U+0020 SPACE
U+1F1EB REGIONAL INDICATOR SYMBOL LETTER F
U+1F1EE REGIONAL INDICATOR SYMBOL LETTER I

而您的错误文件会解码为以下序列:

U+005A LATIN CAPITAL LETTER Z
U+0065 LATIN SMALL LETTER E
U+0020 SPACE
U+D83C HIGH SURROGATE - invalid!
U+DDEB LOW SURROGATE - invalid!
U+D83C HIGH SURROGATE - invalid!
U+DDEE LOW SURROGATE - invalid!

现在,D83C DDEB D83C DDEE 是 Unicode 代码点 U+1F1EB U+1F1EE 的正确 UTF-16 编码形式。这意味着您的原始 Unicode 文本首先编码为 UTF-16,然后 错误地 将 as-is 视为 Unicode 代码点的各个 UTF-16 代码单元(它们不是)然后根据 UTF-8 进行相应编码,从而生成您的错误文件。

如果这是唯一受影响的文件,那么您只需将其字节替换为上面显示的字节即可。但是,如果这是生成编码错误的 UTF-8 文件的较大编码过程的一部分,您以后无法加载这些文件,那么您需要找出错误的 UTF-16 处理发生的位置并修复 问题。