Reputation: 173
I am trying to read a file using BinaryReader
. However, I am having trouble in retrieving the value that is expected.
using (BinaryReader b = new BinaryReader(File.Open("file.dat", FileMode.Open)))
{
int result = b.ReadInt32(); //expected to be 2051
}
"file.dat"
is the following ...
00 00 08 03 00 00 EA 60
The expected result should be 2051
, but it gets something totally irrelevant instead. Note that the result I get everytime is the same.
What is the problem?
Upvotes: 4
Views: 387
Reputation: 28338
00 00 08 03
is 2051, but if the bytes are actually in the file in the order you listed they're in the wrong order. A four-byte integer 0x0803 should be stored as 03 08 00 00
-- least significant byte first or "little-endian".
Offhand I suspect you're getting 50855936 as the answer? That is 00 00 08 03
in most-significant-byte order, "big-endian".
The x86 architecture is little endian; most other architectures are big-endian. Chances are your data file was either saved on a big-endian machine, or was explicitly saved big-endian because that's the standard byte order for "the Internet".
To convert from big-endian to little-endian you just need to switch the order of the four bytes. The easiest way to do that is the IPAddress.NetworkToHostOrder
method ("network" order is big-endian; "host" order for x86 is little-endian.)
Upvotes: 5
Reputation: 45135
You can use BitConverter.IsLittleEndian
to check the endianness of the machine running your code. If it isn't the same endianess as the file you are loading, you will need to reverse the bytes before trying to convert to an int
.
Upvotes: 2
Reputation: 8212
BinaryReader.ReadInt32 expects the data to be in Little Endian format. Your data you presented is in Big Endian.
Here's a sample program that shows the output of how BinaryWriter writes an Int32 to memory:
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();
}
}
}
Running this produces the output:
03 08 00 00
To convert between the two, you could read four bytes using BinaryReader.ReadBytes(4)
, reverse the array, and then use BitConverter.ToInt32
to convert it to a usable int.
byte[] data = reader.ReadBytes(4);
Array.Reverse(data);
int result = BitConverter.ToInt32(data);
Upvotes: 7