【问题标题】:Java equivalent of struct.unpack('d', s.decode('hex'))[0]struct.unpack('d', s.decode('hex'))[0] 的 Java 等价物
【发布时间】:2018-02-23 22:35:52
【问题描述】:

我正在读取一个存储二进制文件的文件。 在 python 中,我可以轻松地解码文件

>>> s = '0000000000A0A240'
>>> s.decode('hex')
'\x00\x00\x00\x00\x00\xa0\xa2@'
>>> import struct
>>> struct.unpack('d', s.decode('hex'))[0]
2384.0

现在我想用Java做同样的解码,有没有类似的?

【问题讨论】:

标签: java python binaryfiles


【解决方案1】:

由于这些字节按 Little-Endian 顺序排列,是 Intel 处理器上的 C 代码,请使用 ByteBuffer 帮助翻转字节:

String s = "0000000000A0A240";
double d = ByteBuffer.allocate(8)
                     .putLong(Long.parseUnsignedLong(s, 16))
                     .flip()
                     .order(ByteOrder.LITTLE_ENDIAN)
                     .getDouble();
System.out.println(d); // prints 2384.0

这里我使用Long.parseUnsignedLong(s, 16) 作为一个快速的方法来执行decode('hex') 8 个字节。


如果数据已经是一个字节数组,这样做:

byte[] b = { 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xA0, (byte) 0xA2, 0x40 };
double d = ByteBuffer.wrap(b)
                     .order(ByteOrder.LITTLE_ENDIAN)
                     .getDouble();
System.out.println(d); // prints 2384.0

以上的进口是:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

【讨论】:

  • 不错,问题是我没有它作为字符串我有它作为一个再见[],类似于 for (byte[] val : redis.getValues()) {... .}
  • @Am1rr3zA 使用 IDE。它将帮助您进行导入。
  • 我稍微简化了从字符串创建字节的过程:ByteBuffer.wrap(DatatypeConverter.parseHexBinary("0000000000A0A240")),但在应用 order 方法后,LITTLE_ENDIAN 也得到了结果2384.0
  • @VladimirL。当然,它看起来更简单,但使用 JAXB 类进行十六进制解析似乎太棒了....糟糕! ....此外,DatatypeConverter 在默认情况下在 Java 9 SE 中不可用。跨度>
  • @VladimirL。它没有被删除,但 JAXB 在 java.xml.bind 模块中,默认情况下未启用。您需要--add-modules java.xml.bind 才能使用它,或者--add-modules java.se.ee 因为它是通过java.se.ee 模块导入的。这就是为什么我说“默认”。
猜你喜欢
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2016-11-02
  • 2016-11-23
  • 2015-06-17
  • 2012-06-03
  • 2013-01-15
  • 1970-01-01
相关资源
最近更新 更多