在 python 代码中解码 Java int 数组——为我的案例找到了解决方法

decode Java int array in python code -- found a workaround for my case

我从 c​​assandra 的 jmx 获得了一些数据。一个元素是这样定义的。 https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java#L358

Java中的返回类型是int[];

import xml.etree.ElementTree as xml
text = requests.get('http://:8081/mbean?objectname=org.apache.cassandra.db:type=xxx,keyspace=x,columnfamily=x&template=identity').text
x = xml.fromstring(text)
>>> for i in x:
...     if i.get('name') == 'SSTableCountPerLevel':
...             p=i

>>> p.items()
[('description', 'Attribute exposed for management'), ('aggregation', 'array'), ('value', '[I@48a6ea00'), ('isnull', 'false'), ('strinit', 'false'), ('type', '[I'), ('availability', 'RO'), ('name', 'SSTableCountPerLevel')]
>>> p.get('value')
'[I@48a6ea00'

那么如何将这个 [I@48a6ea00 转换为 python 中的 int 列表?

@更新 1:

好像JPY是为了这个目的而来的,但是由于缺少文档,我会试试这个并尽快提供更新。

https://github.com/bcdev/jpy

>>> import jpyutil
>>> jpyutil.init_jvm(jvm_maxmem='512M')
>>> import jpy
>>> b = jpy.array('int', [1,2,3])
>>> b.toString()
'[I@3f2a09d5'
>>> b
[I(objectRef=0x7fa66340dfe8)
>>> b[0]
1L
>>> b[2]
3L
>>> dir(b)
['__class__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__jinit__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'equals', 'getClass', 'hashCode', 'notify', 'notifyAll', 'toString', 'wait']

但我仍然无法将字符串转换为 Python 列表,这是我想要的。

@结论:

如果 python 知道 java int 数组的内容,

解码 python 中的 Java int 数组代码应该是可能的,但在上述情况下,[I @48a6ea00 不是java int 数组的内容,它是对java int 数组的内存引用,所以不可能。

我通过 MX4J 获得了这个字符串,我将查看 MX4J 文档以了解 MX4j 如何处理数组。

@更新2:

查了MX4J doucment后,用

写的很清楚
Obviously it has some limitations, like not being able to manipulate data which cannot be obtained from Strings

最后,我使用了JYTHON,完美解决了我的问题。

看起来某个地方的值被错误地转换为对数组的引用 (int[])。您可以打印原始回复吗?即 text 和 xml,即 x 检查哪一步出错了。

所以问题是原始响应只是 return 数组的内部描述符,'[I@48a6ea00' 是那个 int 数组的引用,它是一个 type@address格式,只在特定的JVM内部有意义,不携带实际值信息。即,无法获得价值,因为它已经在响应中丢失了。

如果您得到 string '[I@48a6ea00' 作为响应,那么将此 int[] 数据类型写入数据库的人就做错了。所以 python 或 cassandra 拯救原始数字为时已晚。