为什么 Delphi IBX TWideMemoField 转换 UTF8 字符串中的字节顺序以及如何避免它?

Why Delphi IBX TWideMemoField converts byte order in UTF8 string and how to avoid it?

我在Firebird 3数据库上用的是Delphi2009 with IBX(没办法选择其他技术,我得随机应变)。我有以下定义:

Firebird BLOB 字段定义为:

BLOB SUB_TYPE 0 SEGMENT SIZE 80

TWideMemoField 定义为:

object MainQryNOTES: TWideMemoField
  FieldName = 'NOTES'
  Origin = 'INVOICES.NOTES'
  ProviderFlags = [pfInUpdate]
  BlobType = ftWideMemo
end

测试字符串为“Цель по инфляции, %”,可以从IBExpert软件的BLOB字段中读取为:

26 04 35 04 3B 04 4C 04 20 00 3F 04 3E 04 20 00
38 04 3D 04 44 04 3B 04 4F 04 46 04 38 04 38 04
2C 00 20 00 25 00

奇怪的是 Delphi 颠倒了字节顺序,例如西里尔字符 Ц 的 HEX UTF8 表示为 04 26,但它在数据库中存储为 26 04,类似的情况也与其他字符完全相同(可以借助表 https://www.w3schools.com/charsets/ref_utf_basic_latin.asp and https://www.w3schools.com/charsets/ref_utf_cyrillic.asp 进行检查)。在我的例子中,我只有 2 字节的字符,但我想类似的情况也会出现在 3 字节和 4 字节的 UTF8 字符上。

那么 - 我如何配置 TWideMemoField 以要求不转换 UTF8 字符串的字节顺序?

您的文本未编码为 UTF8,而是编码为 UTF16。字符 Ц 是 U+0426。按照惯例,16 位代码单元以小端字节顺序存储,$26 $04.

换句话说,一切都按预期和设计运行,我认为您无需尝试修复任何东西,因为没有任何损坏。