python - 无法读取使用 Java 保存到二进制文件中的整数 values

我实现了一个过程,用于将从 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();

相似文章