How to convert UTF-8 byte[] to string?
我有一个
在封面之下,它应该只是一个分配和一个memcopy,所以即使它没有实现,它也应该是可能的。
1 | string result = System.Text.Encoding.UTF8.GetString(byteArray); |
至少有四种不同的转换方法。
encoding的getstring
,但是如果这些字节具有非ASCII字符,则无法返回原始字节。
bitconverter.toString
输出是以"-"分隔的字符串,但没有.NET内置方法将字符串转换回字节数组。
convert.tobase64string
使用
注意:输出字符串可以包含"+"、"/"和"="。如果要在URL中使用该字符串,则需要显式地对其进行编码。
httpserverputility.urltokenencode
使用
一个完整的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | byte[] bytes = { 130, 200, 234, 23 }; // A byte array contains non-ASCII (or non-readable) characters string s1 = Encoding.UTF8.GetString(bytes); // ??? byte[] decBytes1 = Encoding.UTF8.GetBytes(s1); // decBytes1.Length == 10 !! // decBytes1 not same as bytes // Using UTF-8 or other Encoding object will get similar results string s2 = BitConverter.ToString(bytes); // 82-C8-EA-17 String[] tempAry = s2.Split('-'); byte[] decBytes2 = new byte[tempAry.Length]; for (int i = 0; i < tempAry.Length; i++) decBytes2[i] = Convert.ToByte(tempAry[i], 16); // decBytes2 same as bytes string s3 = Convert.ToBase64String(bytes); // gsjqFw== byte[] decByte3 = Convert.FromBase64String(s3); // decByte3 same as bytes string s4 = HttpServerUtility.UrlTokenEncode(bytes); // gsjqFw2 byte[] decBytes4 = HttpServerUtility.UrlTokenDecode(s4); // decBytes4 same as bytes |
不知道编码时从字节数组转换为字符串的一般解决方案:
1 2 3 4 5 6 7 8 9 10 |
定义:
1 2 3 4 | public static string ConvertByteToString(this byte[] source) { return source != null ? System.Text.Encoding.UTF8.GetString(source) : null; } |
使用:
1 | string result = input.ConvertByteToString(); |
将
1 2 3 4 5 6 7 8 9 | private string ToString(byte[] bytes) { string response = string.Empty; foreach (byte b in bytes) response += (Char)b; return response; } |
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public static class Ext { public static string ToHexString(this byte[] hex) { if (hex == null) return null; if (hex.Length == 0) return string.Empty; var s = new StringBuilder(); foreach (byte b in hex) { s.Append(b.ToString("x2")); } return s.ToString(); } public static byte[] ToHexBytes(this string hex) { if (hex == null) return null; if (hex.Length == 0) return new byte[0]; int l = hex.Length / 2; var b = new byte[l]; for (int i = 0; i < l; ++i) { b[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); } return b; } public static bool EqualsTo(this byte[] bytes, byte[] bytesToCompare) { if (bytes == null && bytesToCompare == null) return true; // ? if (bytes == null || bytesToCompare == null) return false; if (object.ReferenceEquals(bytes, bytesToCompare)) return true; if (bytes.Length != bytesToCompare.Length) return false; for (int i = 0; i < bytes.Length; ++i) { if (bytes[i] != bytesToCompare[i]) return false; } return true; } } |
还有类unicodeencoding,使用起来很简单:
1 2 3 4 5 | ByteConverter = new UnicodeEncoding(); string stringDataForEncoding ="My Secret Data!"; byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding); Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded)); |
据我所知,任何给定的答案都不能保证正确的行为和无效的终止。在有人以不同的方式向我展示之前,我用以下方法编写了自己的静态类来处理这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Mimics the functionality of strlen() in c/c++ // Needed because niether StringBuilder or Encoding.*.GetString() handle \0 well static int StringLength(byte[] buffer, int startIndex = 0) { int strlen = 0; while ( (startIndex + strlen + 1) < buffer.Length // Make sure incrementing won't break any bounds && buffer[startIndex + strlen] != 0 // The typical null terimation check ) { ++strlen; } return strlen; } // This is messy, but I haven't found a built-in way in c# that guarentees null termination public static string ParseBytes(byte[] buffer, out int strlen, int startIndex = 0) { strlen = StringLength(buffer, startIndex); byte[] c_str = new byte[strlen]; Array.Copy(buffer, startIndex, c_str, 0, strlen); return Encoding.UTF8.GetString(c_str); } |
1 | var convertedString = BitConverter.ToString(byteAttay); |
用于将从文件中读取的字节数组
1 2 | String filename = new String(byteArrFilename.TakeWhile(x => x != 0) .Select(x => x < 128 ? (Char)x : '?').ToArray()); |
我在这里使用
可选地:
1 | var byteStr = Convert.ToBase64String(bytes); |
Hier是一种不用费心编码的结果。我在网络类中使用它,并将二进制对象作为字符串发送。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public static byte[] String2ByteArray(string str) { char[] chars = str.ToArray(); byte[] bytes = new byte[chars.Length * 2]; for (int i = 0; i < chars.Length; i++) Array.Copy(BitConverter.GetBytes(chars[i]), 0, bytes, i * 2, 2); return bytes; } public static string ByteArray2String(byte[] bytes) { char[] chars = new char[bytes.Length / 2]; for (int i = 0; i < chars.Length; i++) chars[i] = BitConverter.ToChar(bytes, i * 2); return new string(chars); } |
根据所选答案,如果使用.net35或.net35 ce,则必须指定要解码的第一个字节的索引和要解码的字节数:
1 | string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length); |
试试这个:
1 | string myresult = System.Text.Encoding.UTF8.GetString(byteArray); |