هل هناك طريقة أقل إيلامًا لتجربت لمخزن مؤقت لا تبدأ في 0؟
-
22-09-2019 - |
سؤال
يجب أن أتعامل مع البايتات الخام في المشروع وأحتاج إلى القيام بشيء من هذا القبيل بشكل أساسي
byte[] ToBytes(){
byte[] buffer=new byte[somelength];
byte[] tmp;
tmp=BitConverter.GetBytes(SomeShort);
buffer[0]=tmp[0];
buffer[1]=tmp[1];
tmp=BitConverter.GetBytes(SomeOtherShort);
buffer[2]=tmp[0];
buffer[3]=tmp[1];
}
أشعر أن هذا خاطئ للغاية ولكن لا يمكنني العثور على طريقة أفضل للقيام بذلك. هل توجد طريقة أسهل؟
المحلول
BinaryWriter فعال للغاية:
byte[] ToBytes() {
var ms = new MemoryStream(somelength);
var bw = new BinaryWriter(ms);
bw.Write(SomeShort);
bw.Write(SomeOtherShort);
return ms.ToArray();
}
نصائح أخرى
لا تحتاج إلى التهيئة tmp
إلى مجموعة جديدة. BitConverter.GetBytes
يخلق مجموعة جديدة ويعيدها لك. ليس هناك الكثير الذي يمكنك فعله حيال ذلك GetBytes
ولكن يمكنك استخدام طرق مثل Buffer.BlockCopy
لتبسيط عملية النسخ.
إذا كنت لا تفعل ذلك في جزء من الرمز الناقص للأداء ، فيمكنك الذهاب إلى حد ما والقيام بأشياء مثل:
IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();
إذا كنت تعرف الحجم مسبقًا (لديك مجموعة من أنواع القيمة) ، فيمكنك استخدام بنية وتعيين قيمك في البنية. ثم استخدام unsafe
رمز لنسخ البايتات الخام. ما زلت ننصح بعدم ذلك إلا إذا كان ذلك ضروريًا لأغراض السرعة. وقد تعتقد أنه مؤلم :)
private struct MyStruct
{
public short A;
public short B;
public MyStruct(short a, short b)
{
A = a;
B = b;
}
}
private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
byte[] buffer = new byte[4]; // where 4 is the size of the struct
fixed (byte* ptr = buffer)
{
*((MyStruct*)ptr) = myStruct;
}
return buffer;
}
مجرد حافة بت ...
buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);
هذا يعني أيضًا أنك تتحكم بشكل كامل في Endian-Ness (في هذه الحالة ، Little-Indian)
يمكنك جعل الكود الخاص بك أقصر قليلاً باستخدام Array.copy ، ولكن لا يوجد أي حمولة أو ما يعادلها في BitConverter التي تضع البايتات مباشرة في المخزن المؤقت.
يمكن BinaryWriter على MemoryStream هل ما تريد؟
لاحظ أنه من خلال تبني اتفاقيات API لـ BitConverter التي لا تحبها ، فأنت تسبب نفس المشكلة لمستخدمي فصلك. بدلاً من ذلك ، اكتب طريقة تقبل cwrinicwriter وتسلسل صفك فيها ، وهذا يمتد بشكل جيد عندما يتم تضمين فصلك في بعض الكائنات الأخرى.