2016-02-25 27 views
0

我有一個由Python進程(實際上是MCDungeon緩存文件)創建的'pickle'格式數據文件。我想從Java程序中讀取它。如何取消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,並要求給出空指針異常的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) ~[?:?] 

當我加載泡椒數據在手動和傳遞給函數,我得到一個NullPointerException異常錯誤在cPickle.load功能:

[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時做了什麼錯誤?有沒有更好的方法來實現這一目標?

預先感謝任何指針(最好不要空的,我有足夠的那些已經!)

回答

0

的問題似乎是,我是用Jython 2.5.3。升級到Jython 2.7.0解決了未解決的問題(儘管我然後遇到了將Python數據類型強制轉換爲Java類型的問題,但這種方法很難實現)

+0

'pickle'格式有多個版本; Jython 2.5.3不支持最新版本,這就是它出錯的原因。然而,就內存而言,使用jython是非常昂貴的方式。自定義對象被醃漬的方式也存在其他問題。 –