Ondra Janoška
Ondra Janoška

Reputation: 3

Can't write binary file in python

I need to write a binary file in python where first few lines are 8 byte ints and the rest a bunch of double precision numbers. How do I best do it? I tried this code, but I got stuck, becuase for some reason, this code generates only text files despite being open in wb.

if binary:
            outfile = open(filename,"wb")
            text = f"1\n8\n{nrcells}\n{nrspecs}\n"
            outfile.write(text.encode(encoding="UTF-8"))
            if self.rho.ndim == 3:
                for x3 in range(self.par["rho_dim"][2]):
                    for x2 in range(self.par["rho_dim"][1]):
                        text="\n".join(f"{d:.8e}" for d in self.rho[:, x2, x3]*10**(-10))+"\n"
                        outfile.write(text.encode(encoding="UTF-8"))

Upvotes: 0

Views: 1391

Answers (1)

Michilus
Michilus

Reputation: 1460

If you want to write binary data, it's not enough to just open the file in binary mode.

When you are executing these lines

text = f"1\n8\n{nrcells}\n{nrspecs}\n"
outfile.write(text.encode(encoding="UTF-8"))

you are still writing textual data to it.

Instead, you may want to have a look at the struct and array standard library modules. They enable you to write your numerical data to bytes objects or files in binary modes.

To write your 1, 8, nrcells, nrspecs header, assuming they are 8 byte integers, you'd do something like this:

# q means "long long", or 8 bytes signed integer
header_bytes_content = struct.pack('qqqq', 1, 8, nrcells, nrspecs)  
outfile.write(header_bytes_content)

To write your float values, you could either write them one by one:

# d means 8 byte floating point; f means 4 byte floating point
float_bytes_content = struct.pack('d', float_value)
outfile.write(float_bytes_content)

or gather all the values into an array and write them to the file:

float_array = array.array('d', float_values)
float_array.tofile(outfile)

To read it back out of the file, you can use struct.unpack and array.fromfile

Note that, if you don't need the file to be binary, you probably shouldn't use a binary format. Textual formats are easier to read and write by code and humans, and usually don't take up much more space.

Upvotes: 1

Related Questions