لدي صفيف byte[]
الذي تم تحميله من ملف أجده معروفًا يحتوي على UTF-8 . في بعض تعليمات تصحيح الأخطاء ، أحتاج إلى تحويلها إلى سلسلة. هل هناك بطانة واحدة ستقوم بذلك؟
تحت الأغطية ، يجب أن يكون مجرد تخصيص و memcopy ، لذلك حتى إذا لم يتم تنفيذه ، فيجب أن يكون ذلك ممكنًا.
string result = System.Text.Encoding.UTF8.GetString(byteArray);
هناك أربع طرق مختلفة على الأقل للقيام بهذا التحويل.
ترميز GetString
، لكن لن تتمكن من استعادة وحدات البايت الأصلية إذا كانت هذه البايتات تحتوي على أحرف غير ASCII.
BitConverter.ToString
الإخراج عبارة عن سلسلة محددة بـ "-" ، ولكن لا توجد طريقة .NET مدمجة لتحويل السلسلة إلى صفيف البايت.
Convert.ToBase64String
يمكنك بسهولة تحويل سلسلة الإخراج إلى صفيف البايت باستخدام Convert.FromBase64String
.
ملاحظة: يمكن أن تحتوي سلسلة الإخراج على '+' ، '/' و '='. إذا كنت تريد استخدام السلسلة في عنوان URL ، فأنت بحاجة إلى ترميزها بشكل صريح.
HttpServerUtility.UrlTokenEncode
يمكنك بسهولة تحويل سلسلة الإخراج إلى صفيف البايت باستخدام HttpServerUtility.UrlTokenDecode
. سلسلة الإخراج هو بالفعل URL ودية! الجانب السلبي هو أنه يحتاج إلى System.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
حل عام للتحويل من صفيف البايت إلى السلسلة عندما لا تعرف التشفير:
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
بسيطًا ، ولكن من المحتمل أن يؤدي أي نوع من الترميز إلى تعطل سلسلة الإخراج. هذه الوظيفة الصغيرة تعمل فقط دون أي نتائج غير متوقعة:
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);
على حد علمي ، فإن أياً من الإجابات المقدمة لا تضمن السلوك الصحيح بإنهاء لاغٍ. حتى يظهر لي شخص ما بشكل مختلف ، كتبت صفي الثابت الخاص للتعامل مع هذا بالطرق التالية:
// 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[]
كصفيف من السلاسل الفارغة التي تم إنهاؤها. يمكن تجاهلها بأمان في الحالة البسيطة
يمكن استخدام فئة BitConverter
لتحويل byte[]
إلى string
.
var convertedString = BitConverter.ToString(byteAttay);
وثائق BitConverter
class يمكن أن تكون fount on MSDN
سيكون Linq أحادي الاتجاه لتحويل صفيف بايت byteArrFilename
من ملف إلى سلسلة ascii خالصة خالصة من النمط C سيكون هذا: مفيد لقراءة أشياء مثل جداول فهرس الملفات في تنسيقات الأرشيف القديمة.
String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
.Select(x => x < 128 ? (Char)x : '?').ToArray());
يمكنني استخدام '?'
كأحرف افتراضية لأي شيء ليس ascii خالصًا هنا ، ولكن يمكن تغيير ذلك بالطبع. إذا كنت تريد التأكد من قدرتك على اكتشافه ، فما عليك سوى استخدام '\0'
بدلاً من ذلك ، لأن TakeWhile
في البداية يضمن أن السلسلة التي تم إنشاؤها بهذه الطريقة لا يمكن أن تحتوي على قيم '\0'
من مصدر الإدخال.
hier هي نتيجة حيث لم يكن لديك عناء مع الترميز. لقد استخدمتها في فئة الشبكة وأرسل كائنات ثنائية كسلسلة بها.
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 ، فيتعين عليك تحديد فهرس البايت الأول لفك التشفير ، وعدد البايتات المطلوب فك تشفيرها:
string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
جرب هذا:
string myresult = System.Text.Encoding.UTF8.GetString(byteArray);