使用存储在数据库中的字符串编码问题

Wyl*_*rio 1 c# unicode encoding mongodb-.net-driver

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

目前,在从db检索文本时,我尝试了以下代码.

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

第一次尝试:

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);
}
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

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

db中的示例文本:

Box aus Pappef rA8-Lernk rtchen

期望的结果:

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

Box ausPappefürA8-Lernkärtchen

hel*_*elb 5

精简版

您的数据丢失,并且没有一般解决方案如何恢复原始字符串.

更长的版本

存储数据时应该发生的事情,字符串编码为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'
Run Code Online (Sandbox Code Playgroud)

当这个数据(以某种方式......)传递给只适用于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'
Run Code Online (Sandbox Code Playgroud)

问题是字节228(11100100二进制)对utf8无效,因为对于这样的字节,必须跟随其他2个字节,其值> 127.有关详细信息,请参阅维基百科上的UTF8,"描述"一章.

所以会发生的是,以前称为字符'ä'的字节无法解码为有效的unicode字符,并被字节239,191和189替换.这是11101111,10111111和10111101,它们导致代码点具有值1111111111111101(0xFFFD)这是你在输出中看到的字符' '.

该字符用于此目的.在维基百科的Unicode特殊字符页面上,它说:

U +FFFD 用于替换未知或不可代表字符的替换字符

试着恢复这种变化?祝好运.

顺便说一句,Unicode和UTF-8真棒♥,从不使用别的东西☠!