如何用Java去除文件?

时间:2016-02-25 00:37:14

标签: java jython pickle

我有一个' pickle'格式化由Python进程创建的数据文件(实际上是MCDungeon缓存文件)。我想从Java程序中读到这个。

为此,我使用了以下代码:

    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函数(其他地方)。

我传递的文件肯定是一个有效的Picklefile,因为它可以被Python进程成功读取。

但是,在运行此函数时,我在cPickle.load函数中抛出PyException,并在给定NullPointer异常的情况下调用printStackTrace(行号71对应于上面的e3.printStackTrace()行)

[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错误:

[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)

我的问题是:

  1. 当我尝试打印堆栈跟踪时,为什么会出现错误?

  2. 加载picklefile我做错了什么?有没有更好的方法来实现这一目标?

  3. 提前感谢任何指针(最好不是空指针,我已经足够了!)

2 个答案:

答案 0 :(得分:1)

我使用Jython来释放.pkl文件。 Jython提供了Java的python2支持,并且pickle文件应该使用协议代码0,1或2进行序列化。

{
    PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.exec("Your Python code here");

    PyObject getAtrsFunc = interpreter.get("your_python_function_name");
    PyObject funcRes = getImageAtrsFunc.__call__(new PyString("Example_input_String_to_py_function"), new PyInteger(javaIntegerValue));
    //Lets say function returns integer array as an output
    //To convert output to java usable object 
    int [] resAtrs = (int []) funcRes.__tojava__(int [].class);
}

要在maven项目中使用jython,请添加

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.7.0</version>
</dependency>

到您的pom文件

答案 1 :(得分:0)

问题似乎是我使用的是Jython 2.5.3。升级到Jython 2.7.0解决了unickling问题(虽然我遇到了将Python数据类型强制转换为Java类型的问题,但这种问题已经解决了)