4

我正在尝试使用BinaryReader. 但是,我在检索预期值时遇到了麻烦。

using (BinaryReader b = new BinaryReader(File.Open("file.dat", FileMode.Open)))
{
    int result = b.ReadInt32(); //expected to be 2051
}

"file.dat"以下是...

00 00 08 03 00 00 EA 60

预期的结果应该是2051,但它却得到了一些完全不相关的东西。请注意,我每次得到的结果都是一样的。

问题是什么?

4

4 回答 4

7

BinaryReader.ReadInt32期望数据采用 Little Endian 格式。您提供的数据采用 Big Endian。

这是一个示例程序,它显示了 BinaryWriter 如何将 Int32 写入内存的输出:

namespace Endian {
  using System;
  using System.IO;

  static class Program {
    static void Main() {
      int a = 2051;

      using (MemoryStream stream = new MemoryStream()) {
        using (BinaryWriter writer = new BinaryWriter(stream)) {
          writer.Write(a);
        }

        foreach (byte b in stream.ToArray()) {
          Console.Write("{0:X2} ", b);
        }
      }

      Console.WriteLine();
    }
  }
}

运行它会产生输出:

03 08 00 00

要在两者之间进行转换,您可以使用 读取四个字节BinaryReader.ReadBytes(4)反转数组,然后使用BitConverter.ToInt32将其转换为可用的 int。

byte[] data = reader.ReadBytes(4);
Array.Reverse(data);
int result = BitConverter.ToInt32(data);
于 2012-11-19T15:25:11.687 回答
5

00 00 08 03 2051,但如果字节实际上按照您列出的顺序在文件中,则它们的顺序错误。四字节整数 0x0803 应存储为03 08 00 00-- 最低有效字节优先或“小端”。

副手我怀疑你得到 50855936 作为答案?那是00 00 08 03最高有效字节顺序,“big-endian”。

x86 架构是小端的;大多数其他架构都是大端的。很有可能您的数据文件要么保存在大端机器上,要么显式保存大端,因为这是“互联网”的标准字节顺序。

要从 big-endian 转换为 little-endian,您只需切换四个字节的顺序。最简单的方法是IPAddress.NetworkToHostOrder方法(“网络”顺序是大端;x86 的“主机”顺序是小端。)

于 2012-11-19T15:25:10.453 回答
3

根据MSDN BinaryReader.ReadInt32是小端。尝试这个:

using (BinaryReader b = new BinaryReader(File.Open("file.dat", FileMode.Open)))
{
    int result = IPAddress.NetworkToHostOrder(b.ReadInt32()); //expected to be 2051
}
于 2012-11-19T15:25:39.553 回答
2

您可以使用BitConverter.IsLittleEndian检查运行代码的机器的字节顺序。如果它与您正在加载的文件的字节序不同,则需要在尝试转换为int.

于 2012-11-19T15:39:42.877 回答