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

问题描述

尝试使用TStringList.LoadFromFile方法加载文件时,出现以下异常:

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

目标多字节代码页中不存在Unicode字符的映射

该文件为Unicode,并且错误似乎与文件中存在的此特殊字符有关。 example.txt文件只有一行,其内容如下所示:

Ze ??

文件包含以下字节:

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

有什么解决方法吗?

解决方法

您的文件声称已编码为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在错误文件中被误编码为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,然后将其中错误视作“-”的各个UTF-16代码单元作为Unicode代码点(不是),然后进行相应编码到UTF-8,从而产生错误的文件。

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

,

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...