我试图读取与BinaryReader在类的二进制文件,我需要在阅读它作为UInt32的块,然后执行一些比特移位等后记。

但是,对于当我使用ReadUInt32方法某种原因比特顺序是相反的。

如果我例如有一个文件,其中的前四个字节如下所示十六进制,0x12345678,他们最终像这样通过ReadUInt32被读取后:0x78563412

如果我使用的ReadBytes(4)方法中,我得到预期的数组:

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

这是为什么?难道仅仅是.NET表示内存的uint的方式吗?它是在不同的平台相同的(我运行64位Windows 7,.NET 3.5 SP1)?

有帮助吗?

解决方案

这似乎是一个字节序问题。 说ReadUint32在小端读取文档因此,第一个字节是最低显著如此这般以最低的内存位置。你的作家必须是大端?

BinaryWriter.Write(UInt32) href="http://msdn.microsoft.com/en-us/library/d79ecdwh.aspx" rel="noreferrer">说,写小端了。是您的二进制数据源没有的BinaryWriter?

从本质上讲,你需要做的,解决它是这样的:

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

此向上移动的至少-显著字节24个比特,第二LSB起来8位,第3向下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);

其他提示

是的,这与在内存中如何您的计算机硬件商店的uint做。它可以是在不同的平台不同,虽然大多数桌面计算机应是相同的。

此被称为字节序 - 见维基这里:

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

看到乔恩斯基特的MiscUtil库用于Endian的*类,像EndianBinaryReader和EndianBitConverter。

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

这是平台字节序的问题。当你阅读从流数据则必须相应地念给它被写为字节顺序。如果你创建.NET中的数据,然后将净正确读取它。

通用BinaryReader在和的BinaryWriter扩展,一个伟大的方式来处理通用铸造非托管方式。

有关VB.NET(安全代码而已,也可以在C#实现)使用下面的:

进口System.IO 进口System.Runtime.CompilerServices 进口System.Runtime.InteropServices

<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