4

我正在解析 C# 中的 MNIST 数据集,来自:http: //yann.lecun.com/exdb/mnist/

我正在尝试Int32从二进制文件中读取第一个:

FileStream fileS = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fileS);
int magicNumber = reader.ReadInt32();

但是,它给了我一个无意义的数字:50855936。

如果我使用File.ReadAllBytes()

buffer = File.ReadAllBytes(fileName);

然后查看字节,它工作正常(前四个字节现在代表 2049),我对 BinaryReader 做错了什么?

文件格式如下(我正在尝试读取第一个幻数):

All the integers in the files are stored in the MSB first (high endian) format used by most non-Intel processors. Users of Intel processors and other low-endian machines must flip the bytes of the header.

训练集标签文件(train-labels-idx1-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  60000            number of items 
0008     unsignebyte     ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.d 
4

2 回答 2

8

50855936 == 0x03080000。或者当您反转字节时为 0x00000803,这在几乎所有机器上都需要,因为 little-endian 赢得了鸡蛋大战。足够接近 2049,不知道是什么解释了 2 的偏移量。这是一个帮助您阅读它的扩展方法:

  public static class BigEndianUtils {
      public static int ReadBigInt32(this BinaryReader br) {
          var bytes = br.ReadBytes(sizeof(Int32));
          if (BitConverter.IsLittleEndian) Array.Reverse(bytes);
          return BitConverter.ToInt32(bytes, 0);
      }
  }

如果文件包含更多字段类型,请添加其他方法,只需在代码段中替换 Int32 即可。

于 2014-01-07T09:01:29.487 回答
0

看来您的问题出在其他地方。您能否发布一个无法按预期工作的最小可编译片段?

例如,这个片段完全按照预期工作——它创建了一个 8 字节的二进制文件,这是两个大端 Int32。然后阅读器将数据正确地读取为两个整数。

using (var str = File.Create("C:\\Test.dat"))
    using (var wr = new BinaryWriter(str))
    {
        wr.Write(2049);
        wr.Write(60000);
    }

using (var str = File.Open("C:\\Test.dat", FileMode.Open))
    using (var rdr = new BinaryReader(str))
    {
        rdr.ReadInt32().Dump();
        rdr.ReadInt32().Dump();
    }

但是,字节顺序是固定的。如果您需要首先使用 MSB,则需要自己读取字节并将它们转换为整数(或者,如果您愿意,当然可以使用按位运算反转字节顺序)。

于 2014-01-07T08:58:36.337 回答