سؤال

أحاول قراءة ملف ثنائي مع فئة BinaryReader، وأحتاج إلى قراءتها ككتل من UINT32، ثم قم بإجراء تغيير بعض الشيء وما إلى ذلك.

ولكن بالنسبة لبعض طلب الأسباب يتم عكسه عند استخدام طريقة Readoint32.

إذا كان لي على سبيل المثال ملف حيث يبدو أن البايت الأربعة الأولى يشبه ذلك في عرافة، 0x12345678, ، ينتهي بهم الأمر مثل هذا بعد قراءة بواسطة Readoint32: 0x78563412.

إذا كنت تستخدم طريقة ReadBytes (4)، أحصل على الصفيف المتوقع:

[0x00000000]    0x12    byte
[0x00000001]    0x34    byte
[0x00000002]    0x56    byte
[0x00000003]    0x78    byte

لماذا هذا؟ هل هي الطريقة التي يمثلها .NET uints في الذاكرة؟ هل هو نفسه عبر المنصات المختلفة (أنا أقوم بتشغيل 64 بت Windows 7، .NET 3.5 SP1)؟

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

المحلول

هذا يبدو أن يكون الانتخابات مشكلة. المستندات قل Readoint32 يقرأ في Little-Endian، لذا فإن البايت الأول هو الأقل أهمية حتى يذهب إلى أدنى موقع للذاكرة. يجب أن يكون كاتبك كبيرا؟

BinaryWriter.Write(UInt32) يقول إنه يكتب قليل من الانديان أيضا. هو مصدر البيانات الثنائية الخاص بك وليس ثنائي

أساسا ما تحتاج إلى القيام به لإصلاحه هو:

uint a = 0x12345678;
uint b = ((a & 0x000000FF) << 24) + ((a & 0x0000FF00) << 8) + ((a & 0x00FF0000) >> 8) + ((a & 0xFF000000) >> 24);

هذا ينقل البايت البايت الأقل أهمية 24 بت، والثاني LSB 8 بت، والثالثة LSB أسفل 8 بت، و LSB الرابع (MSB) أسفل 24 بت. القيام بذلك مغطاة بالعديد من المكتبات.

ربما تستخدم BitConverter سيكون أكثر وضوحا قليلا:

uint a = 0x12345678;
byte[] bytes = BitConverter.GetBytes(a);
// Swap byte order
uint b = BitConverter.ToUInt32(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0);

نصائح أخرى

نعم، يجب أن تفعل هذا مع كيفية تخزين أجهزة الكمبيوتر الخاصة بك uints في الذاكرة. يمكن أن يكون مختلفا عبر منصات مختلفة، على الرغم من أن معظم أجهزة كمبيوتر سطح المكتب يجب أن تكون هي نفسها.

وهذا ما يسمى الانتقاء - انظر ويكيبيديا هنا:

http://en.wikipedia.org/wiki/endian.

انظر إلى مكتبة جون Skeet's Miscutil للفصول الإندية * مثل EndianBinaryReader و EndianBitonverter.

http://www.yoda.arachsys.com/csharp/miscutil/

Jon Skeet's مكتوبة BitConverter مع Endian-Ness القابل للتكوين. قد تجد أنه من المفيد.

http://www.yoda.arachsys.com/csharp/miscutil/

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

اقرأ مجموعة ثنائية الثانوية العامة, وسيلة رائعة للتعامل مع الصب العام بطريقة غير المدارة.

بالنسبة ل VB.NET (رمز آمن فقط، يمكن أيضا تحقيقه أيضا في C #) استخدم ما يلي:

Imports System.io Imports System.Runtime.compilerservices الواردات

<HideModuleName()>
Public Module BinaryReaderExtensions

 <Extension()>
 Public Function Read(Of T As Structure)(br As BinaryReader) As T
  Dim bytes = br.ReadBytes(Marshal.SizeOf(GetType(T)))
  Dim handle = GCHandle.Alloc(bytes, GCHandleType.Pinned)
  Return Marshal.PtrToStructure(handle.AddrOfPinnedObject, GetType(T))
 End Function

 <Extension()>
 Public Function ReadReverse(Of T As Structure)(br As BinaryReader) As T
  Dim bytes = br.ReadBytes(Marshal.SizeOf(GetType(T))).Reverse.ToArray
  Dim handle = GCHandle.Alloc(bytes, GCHandleType.Pinned)
  Return Marshal.PtrToStructure(handle.AddrOfPinnedObject, GetType(T))
 End Function

End Module

يمكنك الآن تنفيذ نفس الوظيفة ل BitConverter, ، بالنسبة BinaryWriter إلخ.

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