如何将字节转换为string?
我有一个从我刚刚知道包含UTF-8的文件加载的byte[]
数组。 在一些debugging代码中,我需要将其转换为string。 有没有一个class轮可以做到这一点?
在封面之下它应该只是一个分配和一个memcopy ,所以即使它没有被执行,也应该是可能的。
string result = System.Text.Encoding.UTF8.GetString(byteArray);
这种转换至less有四种不同的方式。
-
编码的GetString
,但如果这些字节包含非ASCII字符,则无法返回原始字节。 -
BitConverter.ToString
输出是一个“ – ”分隔string,但没有.NET内置方法将string转换回字节数组。 -
Convert.ToBase64String
您可以使用Convert.FromBase64String
轻松地将输出string转换回字节数组。
注:输出string可以包含“+”,“/”和“=”。 如果要在URL中使用该string,则需要对其进行显式编码。 -
HttpServerUtility.UrlTokenEncode
您可以使用HttpServerUtility.UrlTokenDecode
轻松地将输出string转换回字节数组。 输出string已经是URL友好的! 缺点是它需要System.Web
程序集,如果你的项目不是一个Web项目。
一个完整的例子:
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
当你不知道编码时,一个从字节数组转换为string的通用解决scheme:
static string BytesToStringConverted(byte[] bytes) { using (var stream = new MemoryStream(bytes)) { using (var streamReader = new StreamReader(stream)) { return streamReader.ReadToEnd(); } } }
定义:
public static string ConvertByteToString(this byte[] source) { return source != null ? System.Text.Encoding.UTF8.GetString(source) : null; }
使用:
string result = input.ConvertByteToString();
将byte[]
转换为string
似乎很简单,但任何types的编码都可能会混淆输出string。 这个小function只是没有任何意外的结果:
private string ToString(byte[] bytes) { string response = string.Empty; foreach (byte b in bytes) response += (Char)b; return response; }
使用(byte)b.ToString("x2")
,输出b4b5dfe475e58b67
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,使用非常简单:
ByteConverter = new UnicodeEncoding(); string stringDataForEncoding = "My Secret Data!"; byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding); Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
或者:
var byteStr = Convert.ToBase64String(bytes);
用于将从文件中读取的字节数组byteArrFilename
转换为纯粹的ASCII格式的以零结尾的string的Linq byteArrFilename
程序就是这样的:Handy用于读取旧归档格式的文件索引表。
String filename = new String(byteArrFilename.TakeWhile(x => x != 0) .Select(x => x < 128 ? (Char)x : '?').ToArray());
我用'?'
作为任何不是纯粹ascii在这里的默认字符,但可以改变,当然。 如果你想确定你能检测到它,只需使用'\0'
,因为TakeWhile
在开始时确保以这种方式构build的string不能包含来自输入源的'\0'
值。
BitConverter
类可用于将byte[]
转换为string
。
var convertedString = BitConverter.ToString(byteAttay);
BitConverter
类的文档可以从MSDN上获得
据我所知,没有任何给定的答案保证正确的行为与空终止。 直到有人以不同的方式显示我,我写了我自己的静态类来处理这个与以下方法:
// 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); }
startIndex
的原因是在我正在处理的例子中,我特别需要将一个byte[]
parsing为一个以null结尾的string数组。 在简单情况下可以安全地忽略它