【发布时间】:2014-02-15 07:32:59
【问题描述】:
我有这个文件,其中包含 python pickle 数据流。我必须在 Android 中读取此文件的内容。
例如,如果我想在python中读取这个数据流,我只需使用以下代码
queue = pickle.load(open('filename', 'rb'))
我想在 Android 中实现同样的功能,这样我就可以读取这个 pickle 流数据并将其存储在某种集合中。
我怎样才能做到这一点?
【问题讨论】:
我有这个文件,其中包含 python pickle 数据流。我必须在 Android 中读取此文件的内容。
例如,如果我想在python中读取这个数据流,我只需使用以下代码
queue = pickle.load(open('filename', 'rb'))
我想在 Android 中实现同样的功能,这样我就可以读取这个 pickle 流数据并将其存储在某种集合中。
我怎样才能做到这一点?
【问题讨论】:
更新:这仅适用于泡菜协议 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 只返回一个对象。因为Java是静态类型的 语言,您必须将其转换为适当的类型。参考这个 表,看看你能收到什么。
更新:我使用各种 pickle 协议 (0-3) 运行测试,发现 0 和 1 失败,但 2 和 3 成功。
这是用于生成腌制数据的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.1 运行时,它会失败并显示:
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.2 和data.3 运行时,它会成功。
【讨论】:
Object data = (Map<String, Entry>)unpickler.load(inputStream); 这给了我一个错误 net.razorvine.pickle.PickleException: expected zero arguments for construction of ClassDict 。我在这里做错了吗?
2 或3 进行腌制才能使其工作。查看我的更新了解更多详情。