存储在数据库字符串编码问题(Encoding issue with string stored in

2019-10-21 17:16发布

我有一个编码的问题。 我在我的MongoDB的文本被错误编码。 文本在我的DB源文件中的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");
}

示例文本的DB:

纸板A8 Lernkrtchen的盒子

期望的结果:

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

纸板箱A8学习卡

Answer 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 ,章节“描述”。

那么,什么情况是,前身为字符“a”字节不能被解码成一个有效的Unicode字符,并通过字节替换239,191和189哪个11101111,10111111和10111101这会导致代码点与价值1111111111111101(0xFFFD),这是你在你的输出看人品'。

此字符用于正是目的。 在维基百科的Unicode特殊字符页 ,它说:

U + FFFD替换字符用来代替一个未知的或不可表示的字符

尝试恢复这一变化? 祝好运。

顺便说一句,Unicode和UTF-8是真棒♥,千万不要用别的☠!



文章来源: Encoding issue with string stored in database