我实现了一个过程,用于将从 PostgreSQL 检索到的 32 位有符号整数 values 保存到二进制文件中。
我使用了 ByteArrayOutputStream 和 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);
//...
我的输入数据样本包含这些 values:
0, 0, 42812, 42822, 41483, 0, 0, ...
当我尝试读取我的二进制文件时,我会得到这些:
0, 0, 1017577472, 1185349632, 195166208, 0, 0, ...
为了读取文件,我编写了一个简单的 python 脚本:
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)
任何想法?
回答1
可能您的数字是 Big-Endian (BE),而您尝试解码为 Little-Endian (LE)。
尝试:struct.unpack('>i', chunk)
强制读取为 BE。
另请参阅 https://docs.python.org/3/library/struct.html#byte-order-size-and-alignment。
仅供参考,DataOutputStream
始终如 https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeInt(int) 中所述以 BE 编写。
回答2
好的,问题是使用 LE 的 python 和 java 之间位读取顺序的不同行为。
我需要创建一个遵循 ISOBUS 标准的二进制文件,并且必须使用 LE 编写它。
所以我以这种方式更改我的代码:
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();