在Android中读取python pickle数据流(Read python pickle data stream in Android)

编程入门 行业动态 更新时间:2024-10-27 21:16:47
在Android中读取python pickle数据流(Read python pickle data stream in Android)

我有这个包含python pickle数据流的文件。 我要在Android中阅读此文件的内容。

例如,如果我想在python中读取这个数据流,我只需使用以下代码

queue = pickle.load(open('filename', 'rb'))

我想在Android中实现同样的功能,这样我就可以读取这个pickle流数据并将其存储在某种集合中。

我怎样才能做到这一点?

I have this file which contains python pickle data stream. I've to read contents of this file in Android.

For example, if I wanted to read this data stream in python, I'd just use the following code

queue = pickle.load(open('filename', 'rb'))

I want to achieve same thing in Android such that I can read this pickle stream data and store it in some kind of collection.

How can I achieve this?

最满意答案

更新:这仅适用于泡菜协议2和3 。

我认为来自Pyrolite (MIT许可证)的Unpickler类可能对您特别感兴趣。 它在技术上是Java,但Android基本上是Java。 要解开,你会做类似以下的事情:

InputStream stream = new FileInputStream("filename"); Unpickler unpickler = new Unpickler(); Object data = unpickler.load(stream); // And cast *data* to the appropriate type.

随着进口:

import java.io.FileInputStream; import java.io.InputStream; import net.razorvine.pickle.Unpickler;

这些是默认支持的对象:

PYTHON ----> JAVA ------ ---- None null bool boolean int int long long or BigInteger (depending on size) string String unicode String complex net.razorvine.pickle.objects.ComplexNumber datetime.date java.util.Calendar datetime.datetime java.util.Calendar datetime.time java.util.Calendar datetime.timedelta net.razorvine.pickle.objects.TimeDelta float double (float isn't used) array.array array of appropriate primitive type (char, int, short, long, float, double) list java.util.List<Object> tuple Object[] set java.util.Set dict java.util.Map bytes byte[] bytearray byte[] decimal BigDecimal custom class Map<String, Object> (dict with class attributes including its name in "__class__")

还请注意:

unpickler只返回一个Object。 因为Java是一种静态类型语言,所以必须将其转换为适当的类型。 请参阅此表以了解您可以接收的内容。


更新:我使用各种pickle协议( 0-3 )运行测试,发现它为0和1失败,但成功为2和3 。

这是用于生成pickle数据的python代码:

import pickle class Data(object): def __init__(self): self.x = 12 data = Data() for p in [0, 1, 2]: with open('data.{}'.format(p), 'wb') as fh: pickle.dump(data, fh, protocol=p) # Python 3 only. with open('data.3', 'wb') as fh: pickle.dump(data, fh, protocol=3)

以及解开它的java代码:

import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.util.Map; import net.razorvine.pickle.Unpickler; public class Test { public static void main(String[] args) throws IOException { String filename = args[0]; InputStream inputStream = new FileInputStream(filename); Unpickler unpickler = new Unpickler(); Map<String, Object> data = (Map<String, Object>)unpickler.load(inputStream); } }

当使用data.0和data.0运行时,它失败了:

Exception in thread "main" net.razorvine.pickle.PickleException: expected zero arguments for construction of ClassDict (for copy_reg._reconstructor) at net.razorvine.pickle.objects.ClassDictConstructor.construct(ClassDictConstructor.java:23) at net.razorvine.pickle.Unpickler.load_reduce(Unpickler.java:617) at net.razorvine.pickle.Unpickler.dispatch(Unpickler.java:170) at net.razorvine.pickle.Unpickler.load(Unpickler.java:84) at Test.main(Test.java:13)

当使用data.3和data.3运行时,它会成功。

UPDATE: This only works for pickle protocols 2 and 3.

I think the Unpickler class from Pyrolite (MIT license) may be of particular interest to you. It is technically Java, but Android is basically Java. To unpickle you would do something similar to the following:

InputStream stream = new FileInputStream("filename"); Unpickler unpickler = new Unpickler(); Object data = unpickler.load(stream); // And cast *data* to the appropriate type.

With the imports:

import java.io.FileInputStream; import java.io.InputStream; import net.razorvine.pickle.Unpickler;

These are the objects supported by default:

PYTHON ----> JAVA ------ ---- None null bool boolean int int long long or BigInteger (depending on size) string String unicode String complex net.razorvine.pickle.objects.ComplexNumber datetime.date java.util.Calendar datetime.datetime java.util.Calendar datetime.time java.util.Calendar datetime.timedelta net.razorvine.pickle.objects.TimeDelta float double (float isn't used) array.array array of appropriate primitive type (char, int, short, long, float, double) list java.util.List<Object> tuple Object[] set java.util.Set dict java.util.Map bytes byte[] bytearray byte[] decimal BigDecimal custom class Map<String, Object> (dict with class attributes including its name in "__class__")

Please also note:

The unpickler simply returns an Object. Because Java is a statically typed language you will have to cast that to the appropriate type. Refer to this table to see what you can expect to receive.


UPDATE: I ran tests using the various pickle protocols (0-3) and found that it fails for 0 and 1, but succeeds for 2 and 3.

Here's the python code used to generate the pickled data:

import pickle class Data(object): def __init__(self): self.x = 12 data = Data() for p in [0, 1, 2]: with open('data.{}'.format(p), 'wb') as fh: pickle.dump(data, fh, protocol=p) # Python 3 only. with open('data.3', 'wb') as fh: pickle.dump(data, fh, protocol=3)

And the java code to unpickle it:

import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.util.Map; import net.razorvine.pickle.Unpickler; public class Test { public static void main(String[] args) throws IOException { String filename = args[0]; InputStream inputStream = new FileInputStream(filename); Unpickler unpickler = new Unpickler(); Map<String, Object> data = (Map<String, Object>)unpickler.load(inputStream); } }

When run with data.0 and data.1, it fails with:

Exception in thread "main" net.razorvine.pickle.PickleException: expected zero arguments for construction of ClassDict (for copy_reg._reconstructor) at net.razorvine.pickle.objects.ClassDictConstructor.construct(ClassDictConstructor.java:23) at net.razorvine.pickle.Unpickler.load_reduce(Unpickler.java:617) at net.razorvine.pickle.Unpickler.dispatch(Unpickler.java:170) at net.razorvine.pickle.Unpickler.load(Unpickler.java:84) at Test.main(Test.java:13)

When run with data.2 and data.3, it succeeds.

更多推荐

本文发布于:2023-07-22 07:01:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1217933.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据流   pickle   python   Android   data

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!