在C#中将字符串(UTF-16)转换为UTF-8

Cel*_*ero 18 .net c# encoding utf-8

我需要在C#中将字符串转换为UTF-8.我已经尝试了很多方法,但没有一个像我想的那样工作.我将我的字符串转换为字节数组,然后尝试将其写入XML文件(编码为UTF-8 ....)但是我得到了相同的字符串(根本没有编码)要么我得到了一个列表无用的字节....有人面临同样的问题吗?

编辑:这是我使用的一些代码:

str= "testé";
byte[] utf8Bytes = Encoding.UTF8.GetBytes(str);
return Encoding.UTF8.GetString(utf8Bytes);
Run Code Online (Sandbox Code Playgroud)

结果是"testé"或者我期待像"testé"这样的东西......

小智 17

如果你想要一个UTF8字符串,每个字节都是正确的('Ö' - > [195,0],[150,0]),你可以使用以下:

public static string Utf16ToUtf8(string utf16String)
{
   /**************************************************************
    * Every .NET string will store text with the UTF16 encoding, *
    * known as Encoding.Unicode. Other encodings may exist as    *
    * Byte-Array or incorrectly stored with the UTF16 encoding.  *
    *                                                            *
    * UTF8 = 1 bytes per char                                    *
    *    ["100" for the ansi 'd']                                *
    *    ["206" and "186" for the russian '?']                   *
    *                                                            *
    * UTF16 = 2 bytes per char                                   *
    *    ["100, 0" for the ansi 'd']                             *
    *    ["186, 3" for the russian '?']                          *
    *                                                            *
    * UTF8 inside UTF16                                          *
    *    ["100, 0" for the ansi 'd']                             *
    *    ["206, 0" and "186, 0" for the russian '?']             *
    *                                                            *
    * We can use the convert encoding function to convert an     *
    * UTF16 Byte-Array to an UTF8 Byte-Array. When we use UTF8   *
    * encoding to string method now, we will get a UTF16 string. *
    *                                                            *
    * So we imitate UTF16 by filling the second byte of a char   *
    * with a 0 byte (binary 0) while creating the string.        *
    **************************************************************/

    // Storage for the UTF8 string
    string utf8String = String.Empty;

    // Get UTF16 bytes and convert UTF16 bytes to UTF8 bytes
    byte[] utf16Bytes = Encoding.Unicode.GetBytes(utf16String);
    byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);

    // Fill UTF8 bytes inside UTF8 string
    for (int i = 0; i < utf8Bytes.Length; i++)
    {
        // Because char always saves 2 bytes, fill char with 0
        byte[] utf8Container = new byte[2] { utf8Bytes[i], 0 };
        utf8String += BitConverter.ToChar(utf8Container, 0);
    }

    // Return UTF8
    return utf8String;
}
Run Code Online (Sandbox Code Playgroud)

在我的例子中,DLL请求也是UTF8字符串,但不幸的是UTF8字符串必须用UTF16编码解释('Ö' - > [195,0],[19,32]).所以150'的ANSI' - '必须转换为UTF16' - '即8211.如果你也有这种情况,你可以使用以下代码:

public static string Utf16ToUtf8(string utf16String)
{
    // Get UTF16 bytes and convert UTF16 bytes to UTF8 bytes
    byte[] utf16Bytes = Encoding.Unicode.GetBytes(utf16String);
    byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);

    // Return UTF8 bytes as ANSI string
    return Encoding.Default.GetString(utf8Bytes);
}
Run Code Online (Sandbox Code Playgroud)

或Native-Method:

[DllImport("kernel32.dll")]
private static extern Int32 WideCharToMultiByte(UInt32 CodePage, UInt32 dwFlags, [MarshalAs(UnmanagedType.LPWStr)] String lpWideCharStr, Int32 cchWideChar, [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpMultiByteStr, Int32 cbMultiByte, IntPtr lpDefaultChar, IntPtr lpUsedDefaultChar);

public static string Utf16ToUtf8(string utf16String)
{
    Int32 iNewDataLen = WideCharToMultiByte(Convert.ToUInt32(Encoding.UTF8.CodePage), 0, utf16String, utf16String.Length, null, 0, IntPtr.Zero, IntPtr.Zero);
    if (iNewDataLen > 1)
    {
        StringBuilder utf8String = new StringBuilder(iNewDataLen);
        WideCharToMultiByte(Convert.ToUInt32(Encoding.UTF8.CodePage), 0, utf16String, -1, utf8String, utf8String.Capacity, IntPtr.Zero, IntPtr.Zero);

        return utf8String.ToString();
    }
    else
    {
        return String.Empty;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要反过来,请参阅Utf8ToUtf16.希望我能提供帮助.


Tho*_*que 15

C#中的字符串总是 UTF-16,没有办法"转换"它.只要您在内存中操作字符串,编码就无关紧要了,只有将字符串写入流(文件,内存流,网络流......)才有意义.

如果要将字符串写入XML文件,只需在创建时指定编码 XmlWriter


Jon*_*han 0

检查 Jon Skeet 对另一个问题的回答:UTF-16 to UTF-8 conversion (for scripting in Windows)

它包含您需要的源代码。

希望能帮助到你。