【问题标题】:Encoding issue with string stored in database存储在数据库中的字符串的编码问题
【发布时间】:2015-01-29 14:18:25
【问题描述】:

我有一个编码问题。我的 MongoDB 中有错误编码的文本。我数据库中文本的源文件以 ISO-8859-1 编码。现在,在我的数据库中查看它时,一些字符被破坏了(变成'�')。

目前,在从数据库中检索文本时,我尝试了以下代码。

var t = Collection.FindOne(Query.EQ("id", "2014121500892"));
string message = t["b203"].AsString;
Console.WriteLine(ChangeEncoding(message));

第一次尝试:

static string ChangeEncoding(string message)
{

    System.Text.Encoding srcEnc = System.Text.Encoding.GetEncoding("ISO-8859-1");
    System.Text.Encoding destEnc = System.Text.Encoding.GetEncoding("UTF-8");
    byte[] bData = srcEnc.GetBytes(message);
    byte[] bResult = System.Text.Encoding.Convert(srcEnc, destEnc, bData);
    return destEnc.GetString(bResult);
}

第二次尝试:

static string ChangeEncoding(string message)
{
    File.WriteAllText("text.txt", message, Encoding.GetEncoding("ISO-8859-1"));
    return File.ReadAllText("text.txt");
}

数据库中的示例文本:

Box aus Pappe f�r A8-Lernk�rtchen

想要的结果:

我希望能够在控制台中将其打印为:

Box aus Pappe für A8-Lernkärtchen

【问题讨论】:

  • 你在看什么?例如,如果您的 IDE 未设置为该编码,它将不知道如何显示该字符。字节明智它可能是正确的。
  • 我刚刚尝试在控制台屏幕上查看。 Console.WriteLine(结果在这里);
  • @WylanOsorio 我将问题标题更新为更具体。我很遗憾地说你运气不好(见我的回答)

标签: c# unicode encoding mongodb-.net-driver


【解决方案1】:

短版

您的数据丢失了,没有通用的解决方案如何恢复原始字符串。

加长版

存储数据时可能发生的情况,字符串编码为 ISO-8859-1,但存储为 Unicode UTF8。这是一个例子:

string orig = "Lernkärtchen";
byte[] iso88891Bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(orig);
// { 76, 101, 114, 110, 107, 228, 114, 116, 99, 104, 101, 110 }
//  'L', 'e', 'r', 'n', 'k', 'ä', 'r', 't', 'c', 'h', 'e', 'n'

当这个数据被传递(不知何故......)到仅适用于 Unicode 字符串的数据库时:

string storedValue = Encoding.UTF8.GetString(iso88891Bytes);
byte[] dbData = Encoding.UTF8.GetBytes(storedValue);
// { 76, 101, 114, 110, 107, 239, 191, 189, 114, 116, 99, 104, 101, 110 }
//  'L', 'e', 'r', 'n', 'k',      '�',     'r', 't', 'c', 'h', 'e', 'n'

问题是字节 228(二进制 11100100)对于 utf8 无效,因为对于这样的字节,后面必须有 2 个其他字节的值 > 127。 详情见UTF8 on Wikipedia,“描述”一章。

所以发生的情况是,以前称为字符“ä”的字节无法解码为有效的 unicode 字符,而是被字节 239、191 和 189 替换。即 11101111、10111111 和 10111101 导致代码值为 1111111111111101 (0xFFFD) 的点,这是您在输出中看到的字符“�”。

此字符正是用于此目的。在Wikipedia Unicode special characters page 上面写着:

U+FFFD - 用于替换未知或无法表示的字符的替换字符

尝试恢复该更改?祝你好运。

顺便说一句,Unicode 和 UTF-8 都很棒♥,永远不要使用其他任何东西☠!

【讨论】:

    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 2017-08-17
    • 2011-07-23
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    相关资源
    最近更新 更多