在C#中使用BinaryReader解析MNIST数据集我做错了什么?

时间:2014-01-07 08:32:10

标签: c# binary endianness mnist

我在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.

TRAINING SET LABEL FILE(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 

2 个答案:

答案 0 :(得分:7)

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。

答案 1 :(得分: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,你需要读取字节并自己将它们转换为整数(或者,你当然可以使用按位运算来反转字节顺序,如果你愿意的话)。