如何用Java解开文件? [英] How to unpickle a file in Java?
问题描述
我有一个由Python进程创建的棘手"格式的数据文件(实际上是MCDungeon缓存文件).我想从Java程序中读取它.
I have a 'pickle' format datafile that was created by a Python process (actually, the MCDungeon cache file). I want to read this from a Java program.
为此,我使用了以下代码:
To do this, I have used this code:
public HashMap<String, Object> getDataFileStream(String filename) {
HashMap<String, Object> data = new HashMap<String, Object>();
File f = new File(filename);
InputStream fs = null;
try {
fs = new FileInputStream(f);
} catch (FileNotFoundException e) {
Log.warning("Pickle file '"+filename+"' not found!");
return null;
}
PyFile picklefile = new PyFile(fs);
PyDictionary phash = null;
try {
phash = (PyDictionary) cPickle.load(picklefile);
} catch ( PyException e3 ) {
log.severe("Cannot unpickle! (Python error)");
e3.printStackTrace(); // throws a null pointer exception
return null;
} catch ( Exception e ) {
log.severe("Cannot unpickle! Err: " + e.getClass().getName());
e.printStackTrace();
return null;
}
ConcurrentMap<PyObject, PyObject> aMap = phash.getMap();
for (Map.Entry<PyObject, PyObject> entry : aMap.entrySet()) {
String keyval = entry.getKey().toString();
PyObject tileentity = (PyList) entry.getValue();
try {
data.put(keyval, pythonToJava(tileentity));
} catch (Exception e) {
data.put(keyval, tileentity);
}
}
return data;
}
我已经包括了JYthon库和pythonToJava函数(在其他地方).
I have included the JYthon library, and also the pythonToJava function (elsewhere).
我传递的文件绝对是有效的Picklefile,因为Python进程可以成功读取它.
The file I am passing is definitely a valid Picklefile as it can be read by the Python process successfully.
但是,运行此函数时,我在cPickle.load
函数中引发了PyException,并在给定NullPointer异常的情况下调用printStackTrace(行号71对应于上面的e3.printStackTrace()
行)
However, when running this function, I get a PyException thrown in the cPickle.load
function, and calling the printStackTrace given a NullPointer exception (the line number 71 corresponds to the e3.printStackTrace()
line above)
[12:42:18 ERROR]: [DynmapMCDungeon] Cannot unpickle! (Python error)
java.lang.NullPointerException
at org.steveshipway.dynmap.PickleLoader.getDataFileStream(PickleLoader.j
ava:71) ~[?:?]
at org.steveshipway.dynmap.Dungeon.getDungeons(Dungeon.java:28) ~[?:?]
at org.steveshipway.dynmap.DynmapMCDungeon.activate(DynmapMCDungeon.java
:179) ~[?:?]
当我手动加载Pickle数据并传递给函数时,在cPickle.load函数中出现NullPointerException错误:
When I load the Pickle data in manually and pass to the function, I get a NullPointerException error in the cPickle.load function:
[13:56:57 INFO]: [DynmapMCDungeon] Reading in MCDungeon pickle...
[13:56:57 ERROR]: [DynmapMCDungeon] Cannot unpickle the MCDungeon cache! Err: java.lang.NullPointerException
[13:56:57 WARN]: java.lang.NullPointerException
[13:56:57 WARN]: at java.util.Objects.requireNonNull(Unknown Source)
[13:56:57 WARN]: at java.util.Arrays$ArrayList.<init>(Unknown Source)
[13:56:57 WARN]: at java.util.Arrays.asList(Unknown Source)
[13:56:57 WARN]: at org.python.core.PyList.<init>(PyList.java:52)
[13:56:57 WARN]: at org.python.core.PyList.<init>(PyList.java:64)
[13:56:57 WARN]: at org.python.modules.cPickle$Unpickler.load_empty_list(cPickle.java:1909)
[13:56:57 WARN]: at org.python.modules.cPickle$Unpickler.load(cPickle.java:1620)
[13:56:57 WARN]: at org.python.modules.cPickle.load(cPickle.java:636)
[13:56:57 WARN]: at org.steveshipway.dynmap.PickleLoader.getDataFileStream(PickleLoader.java:64)
我的问题是:
-
为什么在尝试打印堆栈跟踪时出现错误?
Why am I getting an error when I try to print the stack trace?
加载picklefile怎么办?有没有更好的方法可以做到这一点?
What am I doing wrong with loading the picklefile? Is there a better way to achieve this?
预先感谢任何指针(最好不是空指针,我已经有足够的指针了!)
Thanks in advance for any pointers (preferably not null ones, I have enough of those already!)
推荐答案
问题似乎是我在使用Jython 2.5.3.升级到Jython 2.7.0可以解决棘手的问题(尽管我随后在将Python数据类型强制转换为Java类型时遇到了问题,但这就是Seaprate)
The problem seems to be that I was using Jython 2.5.3. Upgrading to Jython 2.7.0 solved the unpickling issue (though I then get problems with coercing the Python datatypes into Java types, but that's seaprate)
这篇关于如何用Java解开文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!