如何将字节转换为string?

我有一个从我刚刚知道包含UTF-8的文件加载的byte[]数组。 在一些debugging代码中,我需要将其转换为string。 有没有一个class轮可以做到这一点?

在封面之下它应该只是一个分配和一个memcopy ,所以即使它没有被执行,也应该是可能的。

 string result = System.Text.Encoding.UTF8.GetString(byteArray); 

这种转换至less有四种不同的方式。

  1. 编码的GetString
    ,但如果这些字节包含非ASCII字符,则无法返回原始字节。

  2. BitConverter.ToString
    输出是一个“ – ”分隔string,但没有.NET内置方法将string转换回字节数组。

  3. Convert.ToBase64String
    您可以使用Convert.FromBase64String轻松地将输出string转换回字节数组。
    注:输出string可以包含“+”,“/”和“=”。 如果要在URL中使用该string,则需要对其进行显式编码。

  4. 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数组。 在简单情况下可以安全地忽略它