如何诊断字符编码问题

问题描述 投票:0回答:1

我无法识别似乎与 Postgres 数据库中存在的奇怪字符有关的问题。我使用 Java 从 Postgres 中提取数据并将其加载到 BigQuery 中。有时我注意到一些值似乎在这个过程中无明显原因地发生了变化。经过仔细检查,我发现在所有情况下问题似乎都是由我认为不正常的字符引起的。

Postgres 数据库编码为 UTF-8。 Java编码也是UTF-8。

这是我所看到的示例:

我有一个包含此值的文本字段:

SÅawomir

如果我运行这个 SQL:

select length('SÅawomir')

我得到的值为 9,看起来是正确的。但是,如果我将该字符串导出到文本文件并在十六进制编辑器中查看它(在我的例子中,Visual Studio Code 使用十六进制编辑器扩展),则该字符串的长度看起来是 11,而不是 9。经过仔细检查,第二个和第三个字符由 2 个十六进制值表示,而不是像其他字符那样仅用一个十六进制值表示。第二个和第三个字符由以下 4 个十六进制值表示:

C3 85 C2 82

这是显示这些字符的十六进制编辑器的屏幕截图。正如您所看到的,该字符串似乎有 11 个字符,而不是 9 个:

请帮助我理解这些角色是什么以及我能做些什么。它们是有效的 UTF-8 字符吗?如果是这样,为什么它们应该由 Java 程序转换?我怎样才能阻止这种情况发生?

postgresql utf-8 character-encoding
1个回答
0
投票

这是“双重编码”的情况。

原始字符串一定是“Słavomir”。第二个字母 (ł) 使用 UTF-8 中的两个字节

C582
进行编码。

现在,当 UTF-8 编码的字符串插入数据库时,有人将 PostgreSQL 客户端编码设置为单字节编码,可能是 WINDOWS-1252。因此,PostgreSQL 将这两个字节解释为单独的字符:

C5
是“Å”,
82
是一个不可打印的字符,一个名为“break allowed here”的控制字符。

PostgreSQL 将这两个字符转换为服务器编码 UTF-8,从而将它们转换为您观察到的四个字节。每个字符在 UTF-8 中由两个字节表示。

要解决该问题,您必须将数据库中的字符串更新为其正确值。另外,找到并修复使用错误客户端编码设置运行的客户端程序。

© www.soinside.com 2019 - 2024. All rights reserved.