[英]Switch over UInt64 and uint
我有这个const
值:
private const uint val1 = 0xa1b3a3e4;
private const uint val2 = 0x12b3a4e4;
private const uint val3 = 0xaff3a3e4;
private const UInt64 val4 = 0x736e6f6f70000000;
我想打开我的文件,并检查在前x个字节中是否存在上述值之一:
using (BinaryReader binaryReader = new BinaryReader(File.Open(file, FileMode.Open)))
{
UInt64 val = binaryReader.ReadUInt64();
}
编辑
我读取了前8个字节:
UInt64 val = binaryReader.ReadUInt64();
我需要验证此val
等于val4
。
这是使用十六进制编辑器的文件的第一个字节:
因此,您可以看到这是相同的值,但是仍然使用调试器,我可以看到:
val4 = 8317708086210985984
val = 288230376185266176
为什么我会有这种差异?
正如其他人所建议的那样,问题是BinaryReader.Read*()
以小字节序格式读取数据,即,最高有效字节在后而不是在前。 这与x86类系统的内存体系结构一致,其中最高有效字节存储在地址最高的字节中。
也就是说,当您声明
uint64 val4 = 0x736e6f6f70000000;
然后val4
在内存中表示为:
00 00 00 70 6f 6f 6e 73
当您致电:
UInt64 val = binaryReader.ReadUInt64();
val
存储在内存中
73 6e 6f 6f 70 00 00 00
虽然BinaryReader
不提供读取大端数据的方法,但是一个简单的解决方案是使用扩展方法来提供此功能:
static class BigEndianBinaryReaderExtensions
{
private static T ReadBigEndian<T>(BinaryReader r, Func<byte[], int, T> f)
{
int s = Marshal.SizeOf<T>(); // include System.Runtime.Interop;
byte[] b = new byte[s];
if (r.Read(b, 0, s) != s)
throw new EndOfStreamException();
if (BitConverter.IsLittleEndian) // for correct behavior on big-endian architectures
Array.Reverse(b);
return f(b, 0);
}
public static int ReadInt32BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToInt32);
}
public static uint ReadUInt32BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToUInt32);
}
public static long ReadInt64BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToInt64);
}
public static ulong ReadUInt64BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToUInt64);
}
public static short ReadInt16BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToInt16);
}
public static ushort ReadUInt16BigEndian(this BinaryReader reader)
{
return ReadBigEndian(reader, BitConverter.ToUInt16);
}
}
然后,您可以简单地调用BinaryReader.ReadUInt64BigEndian()
以获得预期的结果,如以下驱动程序所示:
static void Main() {
using (MemoryStream ms = new MemoryStream())
{
ms.Write(new byte[] { 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0, 0, 0 }, 0, sizeof(long));
ms.Seek(0, SeekOrigin.Begin);
using (BinaryReader br = new BinaryReader(ms))
{
ulong n = br.ReadUInt64BigEndian();
Console.WriteLine(n == 0x736e6f6f70000000); // prints True
}
}
}
长的内存中表示0x0011223344556677
是字节77, 66, 55, 44, 33, 22, 11, 00
上的许多计算机。 即,字节从最小部分到最大部分按顺序存储。 如果您想进行此比较,则必须在此处进行一些更改。 反转您正在读取的字节数组,或反转常量中字节的顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.