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)?
是的,这与您的计算机硬件如何将内存存储在内存中有关.虽然大多数台式计算机应该是相同的,但它可以在不同平台上有所不同.
这称为字节序 - 请在此处查看维基百科:
http://en.wikipedia.org/wiki/Endian
这似乎是一个字节序问题. 文档说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)