2014-02-15 108 views
4

我有這個包含python pickle數據流的文件。我必須在Android中閱讀此文件的內容。在Android中讀取python pickle數據流

例如,如果我想讀的蟒蛇這一數據流,我只是用下面的代碼

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

我想達到同樣的事情在Android的,這樣我可以讀這泡菜流數據並將其存儲在某種集合中。

我該如何做到這一點?

回答

6

更新:這隻適用於泡菜協議23

我認爲從Pyrolite(MIT許可證)Unpickler類可能會特別感興趣的你。它在技術上是Java,但Android基本上是Java。要unpickle你會做類似下面的東西:

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只是返回一個Objec噸。由於Java是靜態類型的 語言,因此您必須將其轉換爲適當的類型。請參閱此 表以瞭解您可能期望收到的內容。


更新:我跑了使用各種鹹菜協議(0-3)測試,發現它失敗了01,但成功的23

下面是用來生成醃製數據的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代碼來unpickle它:

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.0data.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.2data.3,它成功了。

+0

感謝您的回覆。這看起來有希望。我的pickle數據流包含自定義類。所以,我這樣使用它'Object data =(Map )unpickler.load(inputStream);'這給了我一個錯誤'net.razorvine.pickle.PickleException:構造期望的零參數ClassDict'。我在這裏做錯了什麼? –

+0

@RajeshGolani它看起來像你需要在Python端使用協議'2'或'3'來醃製它的工作。查看我的更新瞭解更多詳情。 – cpburnz