Reputation: 493
I implemented a procedure for saving 32bit signed integer values, retrieved from PostgreSQL, into a binary file.
I used ByteArrayOutputStream and DataOutputStream
//..
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
//this cycle over my retrieved recordset
while (tdb.next()) {
out.writeInt((tdb.getInteger(1))); //getInteger method extract integer value from recordset
}
//convert into byte array
byte[] bytes = baos.toByteArray();
//create file for output
File fileout = new File("./myfilebin.bin");
//write data
Files.write(fileout.toPath(), bytes);
//...
My input data sample contains these values:
0, 0, 42812, 42822, 41483, 0, 0, ...
When I try to read my binary file, I will get these:
0, 0, 1017577472, 1185349632, 195166208, 0, 0, ...
For reading file I wrote a simple python script:
import struct
with open("./myfilebin.bin", "rb") as f:
for chunk in iter(lambda: f.read(4), ''):
integer_value = struct.unpack('i', chunk)[0]
print(integer_value)
Any idea?
Upvotes: 0
Views: 102
Reputation: 493
Ok, the problem was the different behaviour in bit reading order between python, that uses LE, and java.
I need to create a binary file that follows ISOBUS standards and I have to write it using LE.
So I change my code in this way:
FileOutputStream fout = new FileOutputStream("myfileout.bin");
DataOutputStream out = new DataOutputStream(fout);
while (tdb.next()) {
//convert byte endian behaviour for ISOBUS software compatibility
ByteBuffer bb = ByteBuffer.allocate(4);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(tdb.getInteger(1));
//invert significant byte
bb.flip();
out.write(bb.array());
}
fout.close();
out.close();
Upvotes: 0
Reputation: 1585
Probably your numbers are Big-Endian (BE) and you try to decode as Little-Endian (LE).
Try: struct.unpack('>i', chunk)
to force reading as BE.
See also the docs for struct module on alignment and endianess.
FYI, DataOutputStream
always writes in BE as stated in the official javadoc.
Upvotes: 2