سؤال

لدي byte[] مجموعة التي يتم تحميلها من الملف الذي يحدث لي معروف يحتوي على UTF-8.في بعض تصحيح التعليمات البرمجية, أنا بحاجة إلى تحويلها إلى سلسلة.هل هناك سفينة واحدة من شأنها أن تفعل هذا ؟

تحت الأغطية ينبغي أن يكون مجرد تخصيص ، memcopy, حتى لو لم يتم تنفيذه ، ينبغي أن يكون من الممكن.

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

هناك على الأقل أربع طرق مختلفة القيام بهذا التحويل.

  1. الترميز هو GetString
    , ولكنك لن تكون قادرة على الحصول على النسخة الأصلية بايت مرة أخرى إذا كانت تلك بايت قد أحرف غير ASCII.

  2. BitConverter.ToString
    الإخراج هو "-" محدد السلسلة, ولكن لا يوجد .صافي المدمج في طريقة تحويل السلسلة إلى صفيف بايت.

  3. تحويل.ToBase64String
    يمكنك بسهولة تحويل سلسلة الإخراج إلى صفيف بايت باستخدام Convert.FromBase64String.
    ملاحظة:سلسلة الإخراج يمكن أن تحتوي على '+', '/' و '='.إذا كنت ترغب في استخدام السلسلة في URL ، تحتاج إلى صراحة ترميز.

  4. 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);

ووينق أونيلينير لتحويل صفيف بايت byteArrFilename قراءة من ملف إلى سلسلة النقي أسكي C-أسلوب الصفر منتهية سيكون هذا: مفيد لقراءة أشياء مثل الجداول مؤشر ملف في ارشيف الأشكال القديمة

String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
                              .Select(x => x < 128 ? (Char)x : '?').ToArray());

وأنا استخدم '?' كما شار الافتراضي لأي شيء لا أسكي النقي هنا، ولكن يمكن أن يتغير، بطبيعة الحال. إذا كنت تريد أن تكون متأكد من أنك يمكن الكشف عن ذلك، ومجرد استخدام '\0' بدلا من ذلك، منذ TakeWhile في بداية يضمن أن سلسلة بنيت بهذه الطريقة لا يمكن أن تحتوي على قيم '\0' من مصدر الدخل.

ويمكن استخدامها الدرجة BitConverter لتحويل byte[] إلى string.

var convertedString = BitConverter.ToString(byteAttay);

وثائق من الدرجة BitConverter يمكن أن يكون منبعا على <لأ href = "https://msdn.microsoft.com/en-us/library/system.bitconverter(v=vs.110).aspx" يختلط = "noreferrer نوفولو "> 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[] عن مجموعة من لاغية إنهاء السلاسل. ويمكن تجاهلها بأمان في حالة بسيطة

وهير هو نتيجة لذلك حيث أنت لم داعي للقلق مع الترميز. كنت في الصف شبكتي وإرسال الكائنات الثنائية كسلسلة معها.

        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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top