我正在尝试使用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
,但它会变得完全无关紧要。请注意,我每次得到的结果都是一样的。
有什么问题?
答案 0 :(得分: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)
,reverse the array读取四个字节,然后使用BitConverter.ToInt32
将其转换为可用的int。
byte[] data = reader.ReadBytes(4);
Array.Reverse(data);
int result = BitConverter.ToInt32(data);
答案 1 :(得分:5)
00 00 08 03
是 2051,但如果字节实际上在您列出的顺序文件中,则它们的顺序错误。四字节整数0x0803应存储为03 08 00 00
- 最低有效字节优先或“小端”。
副手我怀疑你得到了50855936作为答案?那是00 00 08 03
最重要的字节顺序,“big-endian”。
x86架构是小端的;大多数其他架构都是大端的。您的数据文件可能保存在big-endian机器上,或者显式保存为big-endian,因为这是“Internet”的标准字节顺序。
要从big-endian转换为little-endian,您只需要切换四个字节的顺序。最简单的方法是IPAddress.NetworkToHostOrder
方法(“网络”顺序是big-endian; x86的“host”顺序是little-endian。)
答案 2 :(得分: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
}
答案 3 :(得分:2)
您可以使用BitConverter.IsLittleEndian
检查运行代码的计算机的字节顺序。如果它与您正在加载的文件的字节顺序不同,则在尝试转换为int
之前,您需要反转字节。