【问题标题】:TStringlist error on loadfromfile : No mapping for the Unicode character exists in the target multi-byte code pageloadfromfile 上的 TStringlist 错误:目标多字节代码页中不存在 Unicode 字符的映射
【发布时间】:2020-08-18 12:51:11
【问题描述】:

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

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

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

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

泽??????????

文件包含这些字节:

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

有什么解决方法吗?

【问题讨论】:

  • 你怎么打电话给LoadFromFile?请包括实际代码,最好是实际的文本文件。您可以使用十六进制编辑器查看其实际数据,并将其作为预格式化文本块发布到此处。
  • 我更新了问题。 “example.txt”文件只有一行,这正是我在问题上的表现。
  • 这还不够。文本文件的实际字节看起来完全不同,具体取决于编码:UTF8、UTF16LE、UTF16BE、UTF32LE 或 UTF32BE,并且在每种情况下,有或没有 BOM(所以有 10 个不同的版本!)。当您在文本编辑器中打开所有这些不同的文本文件时,它们看起来都是一样的。
  • 我刚刚上传了文件并编辑了问题。
  • Stack Overflow 的要求之一是,问题是自包含的,这意味着没有指向任何外部站点或资源的链接,这些链接可能 a) 随时消失,b) 有害。因此,请再次编辑您的问题以在文件中包含字节的十六进制表示。

标签: delphi delphi-xe delphi-10.3-rio


【解决方案1】:

您的文件声称编码为 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,但之后文件的其余部分不是正确的 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 拉丁文大写字母 Z U+0065 拉丁文小写字母 E U+0020 空间 U+1F1EB 区域指标符号字母 F U+1F1EE 区域指标符号字母 I

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

U+005A 拉丁文大写字母 Z U+0065 拉丁文小写字母 E U+0020 空间 U+D83C 高代理 - 无效! U+DDEB LOW SURROGATE - 无效! U+D83C 高代理 - 无效! U+DDEE LOW SURROGATE - 无效!

现在,D83C DDEBD83C DDEE 恰好是 Unicode 代码点 U+1F1EBU+1F1EE 的正确 UTF-16 编码形式。这意味着您的原始 Unicode 文本首先被编码为 UTF-16,然后将单个 UTF-16 代码单元 不正确 视为 Unicode 代码点(它们不是),然后进行相应编码到 UTF-8,从而产生你的坏文件。

如果这是唯一受影响的文件,那么您可以简单地将其字节替换为上面显示的字节。但是,如果这是一个更大的编码过程的一部分,它会生成编码错误的 UTF-8 文件,而您之后无法加载,那么您需要找出错误的 UTF-16 处理发生在哪里并修复那个 em> 问题。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这本身并不能解决问题。 LoadFromFile() 将自动检测 BOM 并解码为 UTF-8,但文件一开始就格式错误,因此在其他地方解决格式错误的编码问题之前,解码为 UTF-8 将无济于事。
    猜你喜欢
    • 2017-03-21
    • 2013-08-14
    • 2014-08-05
    • 2014-11-21
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    相关资源
    最近更新 更多