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 处理发生的位置并修复 问题。
我在尝试使用 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 处理发生的位置并修复 问题。