Home > Mobile >  How to read binary file (created in C#) in python?
How to read binary file (created in C#) in python?

Time:04-19

I created a binary file in C# to store floats.

BinaryFormatter formatter = new BinaryFormatter();
FileStream saveFile = File.Create(my_path);
formatter.Serialize(saveFile, data_to_store);
saveFile.Close();

The data can be read in C# well. But I cannot read it from python.

f = open(path,'rb')
nums=int(os.path.getsize(fpath)/4)
data = struct.unpack('f'*nums,f.read(4*nums))
print(data)
f.close()
data =  np.array(data)

The code above did not work.

CodePudding user response:

It looks like you're trying to serialise a binary array of floats.

If you do that using BinaryFormatter.Serialize(), it will write some header information too. I'm guessing you don't want that.

Also note that BinaryFormatter.Serialize() is obsolete, and Microsoft recommends that you don't use it.

If you just want to write a float array as binary to a file, with no header or other extraneous data, you can do it like this in .NET Core 3.1 or later:

float[] data = new float[10];
using FileStream saveFile = File.Create(@"d:\tmp\test.bin");
saveFile.Write(MemoryMarshal.AsBytes(data.AsSpan()));

If you're using .Net 4.x, you have to do it like this:

float[] data = new float[10];
using FileStream saveFile = File.Create(@"d:\tmp\test.bin");

foreach (float f in data)
{
    saveFile.Write(BitConverter.GetBytes(f), 0, sizeof(float));
}

i.e. you have to convert each float to an array of bytes using BitConverter.GetBytes(), and write that array to the file using Stream.Write().


To read an array of floats from a binary file containing just the float bytes using .Net 4.x:

Firstly you need to know how many floats you will be reading. Let's assume that the entire file is just the bytes from writing an array of floats. In that case you can determine the number of floats by dividing the file length by sizeof(float).

Then you can read each float individually and put it into the array like so (using a BinaryReader to simplify things):

using var readFile = File.OpenRead(@"d:\tmp\test.bin");
using var reader = new BinaryReader(readFile);

int nFloats = (int)readFile.Length / sizeof(float);
float[] input = new float[nFloats];

for (int i = 0; i < nFloats;   i)
{
    input[i] = reader.ReadSingle();
}

Actually you could use BinaryWriter to simplify writing the file in the first place. Compare this with the code using BitConverter:

float[] data = new float[10];
using var saveFile = File.Create(@"d:\tmp\test.bin");
using var writer = new BinaryWriter(saveFile);

foreach (float f in data)
{
    writer.Write(f);
}

Note that - unlike BinaryFormatter - BinaryReader and BinaryWriter do not read or write any extraneous header data. They only read and write what you ask them to.

  • Related