我需要在C#中将字符串转换为UTF-8。我已经尝试了很多方法,但没有一个像我想的那样工作。 我将我的字符串转换为字节数组,然后尝试将其写入XML文件(编码为UTF-8 ....)但是我得到了相同的字符串(根本没有编码)要么我得到了一个列表无用的字节.... 有人面临同样的问题吗?
编辑: 这是我使用的一些代码:
str= "testé";
byte[] utf8Bytes = Encoding.UTF8.GetBytes(str);
return Encoding.UTF8.GetString(utf8Bytes);
结果是“testé”或者我期待的类似“testé”......
答案 0 :(得分:16)
如果你想要一个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;
}
在我的情况下,DLL请求也是UTF8字符串,但不幸的是UTF8字符串必须用UTF16编码解释('Ö' - &gt; [195,0],[19,32])。所以ANSI' - '(150)必须转换为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);
}
或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;
}
}
如果您需要反过来,请参阅Utf8ToUtf16。 希望我能提供帮助。
答案 1 :(得分:14)
C#中的字符串总是 UTF-16,无法“转换”它。只要您在内存中操作字符串,编码就无关紧要了,只有将字符串写入流(文件,内存流,网络流......)才有意义。
如果要将字符串写入XML文件,只需在创建XmlWriter
答案 2 :(得分:1)
private 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. *
**************************************************************/
// 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);
char[] chars = (char[])Array.CreateInstance(typeof(char), utf8Bytes.Length);
for (int i = 0; i < utf8Bytes.Length; i++)
{
chars[i] = BitConverter.ToChar(new byte[2] { utf8Bytes[i], 0 }, 0);
}
// Return UTF8
return new String(chars);
}
在原作者帖子中连接字符串。每个sting操作都会导致.Net中的字符串重新创建。 String实际上是一种引用类型。结果,提供的功能将明显变慢。不要这样做。使用字符数组代替,直接写入然后将结果转换为字符串。在我处理500 kb的文本差异的情况下差不多是5分钟。
答案 3 :(得分:0)
答案 4 :(得分:0)
这个例子有帮助吗?
using System;
using System.IO;
using System.Text;
class Test
{
public static void Main()
{
using (StreamWriter output = new StreamWriter("practice.txt"))
{
// Create and write a string containing the symbol for Pi.
string srcString = "Area = \u03A0r^2";
// Convert the UTF-16 encoded source string to UTF-8 and ASCII.
byte[] utf8String = Encoding.UTF8.GetBytes(srcString);
byte[] asciiString = Encoding.ASCII.GetBytes(srcString);
// Write the UTF-8 and ASCII encoded byte arrays.
output.WriteLine("UTF-8 Bytes: {0}", BitConverter.ToString(utf8String));
output.WriteLine("ASCII Bytes: {0}", BitConverter.ToString(asciiString));
// Convert UTF-8 and ASCII encoded bytes back to UTF-16 encoded
// string and write.
output.WriteLine("UTF-8 Text : {0}", Encoding.UTF8.GetString(utf8String));
output.WriteLine("ASCII Text : {0}", Encoding.ASCII.GetString(asciiString));
Console.WriteLine(Encoding.UTF8.GetString(utf8String));
Console.WriteLine(Encoding.ASCII.GetString(asciiString));
}
}
}
答案 5 :(得分:0)
class Program
{
static void Main(string[] args)
{
String unicodeString =
"This Unicode string contains two characters " +
"with codes outside the traditional ASCII code range, " +
"Pi (\u03a0) and Sigma (\u03a3).";
Console.WriteLine("Original string:");
Console.WriteLine(unicodeString);
UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
byte[] utf16Bytes = unicodeEncoding.GetBytes(unicodeString);
char[] chars = unicodeEncoding.GetChars(utf16Bytes, 2, utf16Bytes.Length - 2);
string s = new string(chars);
Console.WriteLine();
Console.WriteLine("Char Array:");
foreach (char c in chars) Console.Write(c);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("String from Char Array:");
Console.WriteLine(s);
Console.ReadKey();
}
}