为什么BinaryReader.ReadUInt32()反转位模式?

Egi*_*sen 7 .net 64-bit 32-bit bit-manipulation endianness

我正在尝试使用BinaryReader类读取二进制文件,我需要将其作为UInt32的块读取,然后在后面进行一些位移等操作.

但是,由于某种原因,当我使用ReadUInt32方法时,位顺序是相反的.

如果我例如有一个文件,其中前四个字节看起来像这样十六进制的,0x12345678他们最终就这样被ReadUInt32读取后:0x78563412.

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

[0x00000000]    0x12    byte
[0x00000001]    0x34    byte
[0x00000002]    0x56    byte
[0x00000003]    0x78    byte
Run Code Online (Sandbox Code Playgroud)

为什么是这样?这只是方式.net代表内存中的uint?在不同的平台上是否相同(我运行64位Windows 7,.net 3.5 sp1)?

Cly*_*yde 8

是的,这与您的计算机硬件如何将内存存储在内存中有关.虽然大多数台式计算机应该是相同的,但它可以在不同平台上有所不同.

这称为字节序 - 请在此处查看维基百科:

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


Col*_*ett 8

这似乎是一个字节序问题. 文档说ReadUint32读取little-endian所以第一个字节是最不重要的,所以它进入最低内存位置.你的作家必须是大头?

BinaryWriter.Write(UInt32) 说它也写了小端.你的二进制数据源不是BinaryWriter吗?

基本上你需要做的就是修复它:

uint a = 0x12345678;
uint b = ((a & 0x000000FF) << 24) + ((a & 0x0000FF00) << 8) + ((a & 0x00FF0000) >> 8) + ((a & 0xFF000000) >> 24);
Run Code Online (Sandbox Code Playgroud)

这将最低有效字节向上移位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);
Run Code Online (Sandbox Code Playgroud)