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

Posted

技术标签:

【中文标题】如何在 C# 中将字符串转换为 UTF-8?【英文标题】:How can I transform string to UTF-8 in C#? 【发布时间】:2012-12-13 00:08:41 【问题描述】:

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

由于编码不正确,我的一段字符串在西班牙语中如下所示:

Ación

而它应该是这样的:

行动

根据这个问题的答案: How to know string encoding in C#,我收到的编码应该已经是 UTF-8,但它是在 Encoding.Default 上读取的(可能是 ANSI?)。

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

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

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);

你们还有什么我可以尝试的想法吗?

【问题讨论】:

您的问题首先来自创建字符串(来自流或字节 [])的代码。请出示该代码。 @Oded:.Net 字符串以 UTF16 格式存储在内存中,但 Encoding.Default 返回系统的 ANSI 代码页。 这是一个在英语中不起作用的字符串示例:我的前端应用程序没有显示 day's ,而是显示:day’s 【参考方案1】:

您知道字符串以Encoding.Default 的形式出现,您可以简单地使用:

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

你可能要记住的另一件事:如果你使用 Console.WriteLine 来输出一些字符串,那么你也应该写Console.OutputEncoding = System.Text.Encoding.UTF8;!!!或者所有的utf8字符串都会输出为gbk...

【讨论】:

这也有效,它实际上比我的回答要好得多,这也有效我给你一个+1的好工作 谢谢!问题是,正如我在描述中提到的,表面的 API 不完整(没有 Encoding.Default 可供我使用)。 @Gaara:试试Encoding.GetEncoding(...);您将需要找到在另一端错误使用的实际编码的名称。 你能解释一下为什么会这样吗?如果 Default 为 GB2312,则 Encoding.Default.GetBytes 将使用 GB2312 编码器将字符串编码为字节数组,然后 Encoding.UTF8.GetString 将尝试使用 UTF8 解码器对字节数组进行解码,结果应该是错误的,但为什么这样会起作用。 @anothershrubery @guorongfei 前提是myString是mojibake。代码首先撤消错误的解码,然后进行正确的解码。只要错误的解码没有丢失数据,它就可以工作。但正如@SLaks 指出的那样,最好使用错误的确切编码。 (代码中更好的名称和 cmets 将有助于理解看起来非常错误的代码实际上是在尝试做正确的事情。)【参考方案2】:
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);

输出应该是这样的

行动

一天的显示 一天的

调用 DecodeFromUtf8();

private static void DecodeFromUtf8()

    string utf8_String = "day’s";
    byte[] bytes = Encoding.Default.GetBytes(utf8_String);
    utf8_String = Encoding.UTF8.GetString(bytes);

【讨论】:

谢谢!它确实适用于西班牙语,问题是同样不适用于东方语言(即韩语)。我正在尝试在互联网上寻找 8 位到 UTF-8 的转换算法,但仍然没有运气。 这是一个在英语中不起作用的字符串示例:我的前端应用程序没有显示 day's ,而是显示:day’s 好吧,让我来看看我能想出什么 我测试过,它会返回 day's 我将粘贴我测试过的静态方法,它实际上与 @anothershrubery 提供的相同 您可以通过传递 DecodeFromUtf8(string utf8string); 来更改该方法;【参考方案3】:

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

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

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

【讨论】:

谢谢!问题是第三方应用程序是 C++,而我的代码是 C#,所以我猜解码发生在这两者之间的“桥梁”中。【参考方案4】:
 Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(mystring));

【讨论】:

【参考方案5】:

@anothershrubery 答案对我有用。我使用StringEntensions Class 进行了增强,因此我可以轻松地在我的程序中转换任何字符串。

方法:

public static class StringExtensions

    public static string ToUTF8(this string text)
    
        return Encoding.UTF8.GetString(Encoding.Default.GetBytes(text));
    

用法:

string myString = "Acción";
string strConverted = myString.ToUTF8();

或者简单地说:

string strConverted = "Acción".ToUTF8();

【讨论】:

【参考方案6】:

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

您的数据库字段结构 i 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) 现在您应该将此值插入到例如名称字段中:

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

4) 许多解决方案没有注意到的主要工作是以下行: 您应该使用 addwithvalue 而不是像下面这样添加命令参数:

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

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

【讨论】:

【参考方案7】:

使用下面的代码 sn-p 从 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();

【讨论】:

以上是关于如何在 C# 中将字符串转换为 UTF-8?的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在C#中将字符串转换为整数

如何在 C# 中将字符串转换为 DateTime?

如何在c#中将ArrayList转换为字符串数组(字符串[])

如何在 C# 中将字符串转换为字节 []

如何在c#中将字符串转换为日期[重复]