باستخدام C#, ما هي الطريقة الأكثر كفاءة تحويل سلسلة التي تحتوي على البيانات الثنائية إلى صفيف من البايت
سؤال
في حين أن هناك 100 سبل حل مشكلة تحويل, أنا مع التركيز على الأداء.
تعطي هذه السلسلة يحتوي فقط على البيانات الثنائية ما هي أسرع طريقة من حيث الأداء ، تحويل البيانات إلى byte[] (لا char[]) تحت C# ؟
التوضيح:ليست هذه هي البيانات ASCII بدلا من البيانات الثنائية التي يحدث أن تكون في سلسلة.
المحلول
لست متأكدا ASCIIEncoding.GetBytes هو ذاهب للقيام بذلك ، لأنه يعتمد فقط على مجموعة 0x0000 إلى 0x007F.
تقول السلسلة يحتوي فقط بايت.ولكن .صافي السلسلة مجموعة من حرف ، 1 شار 2 بايت (لأن .صافي متاجر السلاسل كما UTF16).بحيث يمكنك إما حالتين لتخزين بايت 0x42 و 0x98:
- السلسلة كانت سلسلة ANSI و الواردة بايت و يتم تحويلها إلى سلسلة أحرف unicode ، وبالتالي بايت سيكون 0x00 0x42 0x00 0x98.(يتم تخزين السلسلة 0x0042 و 0x0098)
- السلسلة فقط صفيف بايت التي 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 على السؤال الأصلي يلخص الامر بشكل جيد.;]