باستخدام C#, ما هي الطريقة الأكثر كفاءة تحويل سلسلة التي تحتوي على البيانات الثنائية إلى صفيف من البايت

StackOverflow https://stackoverflow.com/questions/72176

  •  09-06-2019
  •  | 
  •  

سؤال

في حين أن هناك 100 سبل حل مشكلة تحويل, أنا مع التركيز على الأداء.

تعطي هذه السلسلة يحتوي فقط على البيانات الثنائية ما هي أسرع طريقة من حيث الأداء ، تحويل البيانات إلى byte[] (لا char[]) تحت C# ؟

التوضيح:ليست هذه هي البيانات ASCII بدلا من البيانات الثنائية التي يحدث أن تكون في سلسلة.

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

المحلول

لست متأكدا ASCIIEncoding.GetBytes هو ذاهب للقيام بذلك ، لأنه يعتمد فقط على مجموعة 0x0000 إلى 0x007F.

تقول السلسلة يحتوي فقط بايت.ولكن .صافي السلسلة مجموعة من حرف ، 1 شار 2 بايت (لأن .صافي متاجر السلاسل كما UTF16).بحيث يمكنك إما حالتين لتخزين بايت 0x42 و 0x98:

  1. السلسلة كانت سلسلة ANSI و الواردة بايت و يتم تحويلها إلى سلسلة أحرف unicode ، وبالتالي بايت سيكون 0x00 0x42 0x00 0x98.(يتم تخزين السلسلة 0x0042 و 0x0098)
  2. السلسلة فقط صفيف بايت التي typecasted أو المستلمة فقط إلى سلسلة وهكذا أصبح التالية بايت 0x42 0x98.(يتم تخزين السلسلة 0x9842)

في الحالة الأولى على النتيجة ستكون 0x42 و 0x3F (ascii ل ""ب"؟").الحالة الثانية سيؤدي 0x3F (ascii ل "?").وهذا أمر منطقي لأن حرف خارج صالح ascii مجموعة التشفير لا تعرف ماذا تفعل مع تلك القيم.

لذلك أنا أتساءل لماذا انها سلسلة مع بايت?

  • ربما يحتوي بايت ترميز سلسلة (على سبيل المثال ، Base64)?
  • ربما يجب أن تبدأ مع شار مجموعة أو صفيف بايت?

إذا كنت حقا لا يكون الوضع 2 و كنت ترغب في الحصول على وحدات البايت من ذلك يجب عليك استخدام UnicodeEncoding.GetBytes المكالمة.لأن ذلك سيعود 0x42 و 0x98.

إذا كنت ترغب في الذهاب من مجموعة شار إلى صفيف بايت, سيكون أسرع طريقة تنظيم..ولكن هذا ليس حقا لطيفة ، ويستخدم ضعف الذاكرة.

public Byte[] ConvertToBytes(Char[] source)
{
    Byte[] result = new Byte[source.Length * sizeof(Char)];
    IntPtr tempBuffer = Marshal.AllocHGlobal(result.Length);
    try
    {
        Marshal.Copy(source, 0, tempBuffer, source.Length);
        Marshal.Copy(tempBuffer, result, 0, result.Length);
    }
    finally
    {
        Marshal.FreeHGlobal(tempBuffer);
    }
    return result;
}

نصائح أخرى

هناك لا شيء من هذا القبيل كما سلسلة ASCII في C#!سلاسل دائما تحتوي على UTF-16.لم يدركوا هذا يؤدي إلى الكثير من المشاكل.وقال الأساليب المذكورة قبل العمل لأنهم يعتبرون السلسلة مثل ترميز UTF-16 و تحويل الحروف إلى رموز ASCII.

/تحرير وردا على التوضيح:كيف البيانات الثنائية تحصل في السلسلة ؟ سلاسل ليس من المفترض أن تحتوي على البيانات الثنائية (استخدام byte[] من أجل ذلك).

إذا كنت تريد أن تذهب من سلسلة إلى البيانات الثنائية ، يجب أن تعرف ما هو ترميز كان يستخدم لتحويل البيانات الثنائية إلى سلسلة في المقام الأول.وإلا قد لا ينتهي مع تصحيح البيانات الثنائية.لذلك ، فإن الطريقة الأكثر كفاءة من المرجح GetBytes() على ترميز فرعية (مثل UTF8Encoding) ، ولكن يجب أن تعرف على وجه اليقين الذي الترميز.

تعليق من قبل كينت Boogaart على السؤال الأصلي يلخص الامر بشكل جيد.;]

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top