首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >切换UInt64和uint

切换UInt64和uint
EN

Stack Overflow用户
提问于 2015-11-08 14:49:42
回答 2查看 398关注 0票数 1

我有这个const值:

代码语言:javascript
复制
private const uint val1 = 0xa1b3a3e4;
private const uint val2 = 0x12b3a4e4;
private const uint val3 = 0xaff3a3e4;
private const UInt64 val4 = 0x736e6f6f70000000;

我想打开我的文件并检查上面的一个值是否存在于第一个x字节处:

代码语言:javascript
复制
using (BinaryReader binaryReader = new BinaryReader(File.Open(file, FileMode.Open)))
{
     UInt64 val = binaryReader.ReadUInt64();
}

编辑

我读取了前8个字节:

代码语言:javascript
复制
UInt64 val = binaryReader.ReadUInt64();

我需要验证这个val是否等于val4

这是使用十六进制编辑器的文件的第一个字节:

因此,正如您可以看到的,这是相同的值,但仍然使用调试器,我可以看到:

val4 = 8317708086210985984

代码语言:javascript
复制
val = 288230376185266176

我为什么会有这种差异?

EN

回答 2

Stack Overflow用户

发布于 2015-11-09 00:21:04

正如其他人所建议的,问题是BinaryReader.Read*()以小endian格式读取数据,也就是说,最重要的字节在最后而不是第一位。这与x86类系统的内存体系结构是一致的,其中最重要的字节存储在具有最高地址的字节中。

也就是说,当你声明

代码语言:javascript
复制
uint64 val4 = 0x736e6f6f70000000;

然后,val4在内存中表示为:

代码语言:javascript
复制
00 00 00 70 6f 6f 6e 73

当你打电话:

代码语言:javascript
复制
UInt64 val = binaryReader.ReadUInt64();

val存储在内存中,作为

代码语言:javascript
复制
73 6e 6f 6f 70 00 00 00

虽然BinaryReader不提供读取大端数据的方法,但一个简单的解决方案是使用扩展方法来提供此功能:

代码语言:javascript
复制
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()以获得预期的结果,如下面的驱动程序所示:

代码语言:javascript
复制
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
        }
    }
}
票数 4
EN

Stack Overflow用户

发布于 2015-11-08 18:12:39

0x0011223344556677的内存表示形式是许多计算机上的字节77, 66, 55, 44, 33, 22, 11, 00 .也就是说,字节按从最小部分到最大部分的顺序存储。如果您想要进行这种比较,必须在这里反转一些东西;要么反转正在读取的字节数组,要么反转常量中字节的顺序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33595241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档