如何在C#中将字符串转换为UTF-8?


146

我有一个从第三方应用程序收到的字符串,我想在Windows Surface上使用C#以任何语言正确显示它。

由于编码不正确,我的一部分字符串在西班牙语中看起来像这样:

Acción

而它应该看起来像这样:

Acción

根据关于这个问题的答案: 如何知道C#中的字符串编码,我正在接收的编码应该已经在UTF-8上了,但是它是在Encoding.Default(可能是ANSI?)上读取的。

我正在尝试将此字符串转换为真正的UTF-8,但是问题之一是我只能看到Encoding类的一个子集(仅适用于UTF8和Unicode属性),可能是因为我仅限于Windows Surface API。

我尝试了一些在互联网上找到的代码片段,但到目前为止,对于东方语言(例如韩语),它们都没有被证明是成功的。一个示例如下:

var utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(myString);
myString= utf8.GetString(utfBytes, 0, utfBytes.Length);     

我还尝试将字符串提取到字节数组中,然后使用UTF8.GetString:

byte[] myByteArray = new byte[myString.Length];
for (int ix = 0; ix < myString.Length; ++ix)
{
    char ch = myString[ix];
    myByteArray[ix] = (byte) ch;
}

myString = Encoding.UTF8.GetString(myByteArray, 0, myString.Length);

你们还有其他可以尝试的想法吗?


5
您的问题出在最初创建字符串(从流或byte [])中的代码。请显示该代码。
SLaks 2012年

1
@Oded:.Net字符串以UTF16的形式存储在内存中,但Encoding.Default返回系统的ANSI代码页。
SLaks 2012年

这是一个在英语上不起作用的字符串的示例:我的前端应用未显示day,而是显示了:day
Gaara

Answers:


251

如您所知,字符串可以传入,Encoding.Default您可以简单地使用:

byte[] bytes = Encoding.Default.GetBytes(myString);
myString = Encoding.UTF8.GetString(bytes);

您可能还需要记住另一件事:如果您使用Console.WriteLine输出一些字符串,那么您还应该编写Console.OutputEncoding = System.Text.Encoding.UTF8;!!! 否则所有utf8字符串都将输出为gbk ...


这也行得通,实际上比我的回答还要好,我也给您+1不错的工作
MethodMan 2012年

谢谢!问题是,正如我在描述中所提到的,用于表面的API不完整(没有Encoding.Default对我可用)。
加拉拉

3
@Gaara:尝试Encoding.GetEncoding(...);您将需要查找另一端使用不正确的实际编码的名称。
SLaks 2012年

1
您能解释一下为什么行吗?如果Default为GB2312,则Encoding.Default.GetBytes将使用GB2312编码器将字符串编码为字节数组,然后Encoding.UTF8.GetString将尝试使用UTF8解码器对字节数组进行解码,结果应该是错误的,但是为什么这样做有效。@anothershrubery
guorongfei '18

1
@guorongfei前提是那myString是mojibake。代码首先撤消错误的解码,然后进行正确的解码。只要错误的解码没有丢失数据,它就起作用。但是正如@SLaks指出的,最好使用错误的确切编码。(代码中更好的名称和注释将有助于理解看起来错误的代码实际上是在做正确的尝试。)
Tom Blodget

17
string utf8String = "Acción";
string propEncodeString = string.Empty;

byte[] utf8_Bytes = new byte[utf8String.Length];
for (int i = 0; i < utf8String.Length; ++i)
{
   utf8_Bytes[i] = (byte)utf8String[i];
}

propEncodeString = Encoding.UTF8.GetString(utf8_Bytes, 0, utf8_Bytes.Length);

输出应该看起来像

Acción

一天的展示

调用DecodeFromUtf8();

private static void DecodeFromUtf8()
{
    string utf8_String = "day’s";
    byte[] bytes = Encoding.Default.GetBytes(utf8_String);
    utf8_String = Encoding.UTF8.GetString(bytes);
}

1
谢谢!它确实可以用西班牙语工作,但问题是在东方语言(即韩语)上却无法使用。我正在尝试在互联网上寻找一种8位到UTF-8的转换算法,但是仍然没有运气。
加拉拉

这是一个在英语上不起作用的字符串的示例:我的前端应用未显示day,而是显示了:day
Gaara

好的,让我弄乱它,看看我能想到什么
MethodMan 2012年

我测试了一下并返回了一天,我将粘贴我测试过的静态方法实际上与@anothershrubery提供的方法相同
MethodMan 2012年

您可以通过传递DecodeFromUtf8(string utf8string)来更改该方法;
MethodMan 2012年

12

您的代码正在读取UTF8编码的字节序列,并使用8位编码对其进行解码。

您需要修复该代码才能将字节解码为UTF8。

或者(不理想),您可以将错误的字符串转换回原始字节数组(通过使用不正确的编码进行编码),然后将字节重新解码为UTF8。


谢谢!问题是第三方应用程序是C ++,而我的代码是C#,因此我猜想解码发生在这两者之间的“桥梁”中。
加拉拉


5

如果要将任何字符串保存到mysql数据库,请执行以下操作:->

您的数据库字段结构phpmyadmin [或任何其他控制面板]应该设置为utf8-gerneral-ci

2)您应该更改您的字符串[Ex。textbox1.text]到字节,因此

2-1)定义byte [] st2;

2-2)通过以下方式将您的字符串[textbox1.text]转换为unicode [mmultibyte string]:

byte[] st2 = System.Text.Encoding.UTF8.GetBytes(textBox1.Text);

3)在执行任何查询之前执行以下sql命令:

string mysql_query2 = "SET NAMES 'utf8'";
cmd.CommandText = mysql_query2;
cmd.ExecuteNonQuery();

3-2)现在,您应该通过以下方式将此值插入到例如name字段中:

cmd.CommandText = "INSERT INTO customer (`name`) values (@name)";

4)许多解决方案不关注的主要工作是以下行:您应该使用addwithvalue而不是如下所示的add in command参数:

cmd.Parameters.AddWithValue("@name",ut);

++++++++++++++++++++++++++++++++++在数据库服务器中享受真实数据,而不是????


3

使用以下代码片段从csv文件获取字节

protected byte[] GetCSVFileContent(string fileName)
    {
        StringBuilder sb = new StringBuilder();
        using (StreamReader sr = new StreamReader(fileName, Encoding.Default, true))
        {
            String line;
            // Read and display lines from the file until the end of 
            // the file is reached.
            while ((line = sr.ReadLine()) != null)
            {
                sb.AppendLine(line);
            }
        }
        string allines = sb.ToString();


        UTF8Encoding utf8 = new UTF8Encoding();


        var preamble = utf8.GetPreamble();

        var data = utf8.GetBytes(allines);


        return data;
    }

致电以下内容并将其另存为附件

           Encoding csvEncoding = Encoding.UTF8;
                   //byte[] csvFile = GetCSVFileContent(FileUpload1.PostedFile.FileName);
          byte[] csvFile = GetCSVFileContent("Your_CSV_File_NAme");


        string attachment = String.Format("attachment; filename={0}.csv", "uomEncoded");

        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();
        Response.ContentType = "text/csv";
        Response.ContentEncoding = csvEncoding;
        Response.AppendHeader("Content-Disposition", attachment);
        //Response.BinaryWrite(csvEncoding.GetPreamble());
        Response.BinaryWrite(csvFile);
        Response.Flush();
        Response.End();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.