2012-01-13 14 views
3

現在、Plistファイルを読み込むためにPlistlibモジュールを使用していますが、現在はバイナリPlistファイルに関しては問題があります。PythonでバイナリPlistファイルを読む

私はplutil関数を使用せずにバイナリファイルをXMLに変換せずにバイナリPlistファイルを読み込んでいるのかどうか、後で解析/印刷するためにデータを文字列に読み込みたいと思っていますか?

ご協力いただきありがとうございます。

+1

[バイナリplistのためのPythonモジュール]の可能性のある重複(http://stackoverflow.com/q/3725268/222914) –

+0

ありがとうJanne、私はこの記事を見ましたが、別のモジュールをインストールせずに上記を実行する方法を知っていて、あらかじめインストールされているモジュールPythonで利用可能です。 –

+0

デフォルトのモジュールplistlibは、バイナリplistファイルを処理しません。あなたは "biplist"または他の第3のモジュールを選ぶほうがいいでしょう。 –

答えて

2

ツールplutil(libplist from http://www.libimobiledevice.org/)を使用すると、バイナリをxml plistファイルに変換できます(逆も同様です)。インストールは簡単またはPIPを介して利用可能

import json 
from subprocess import Popen, PIPE 

def plist_to_dictionary(filename): 
    "Pipe the binary plist through plutil and parse the JSON output" 
    with open(filename, "rb") as f: 
     content = f.read() 
    args = ["plutil", "-convert", "json", "-o", "-", "--", "-"] 
    p = Popen(args, stdin=PIPE, stdout=PIPE) 
    out, err = p.communicate(content) 
    return json.loads(out) 

print plist_to_dictionary(path_to_plist_file) 
4

あなたは何plutilを指定していないが、それはマックにプリインストールされていて、それに作業溶液が他の人に有用である可能性があります。

+1

この関数に十分な大きさの入力を与えると、p.stdin.write(content)にスタックされます。ドキュメントをお読みください。 – zhangyoufu

+0

@zhangyoufu正直、ありがとう – orip

0

あなたはそれがファイルに基づいてC.

に実装されているか確認するためにCFBinaryPList.cソースファイルを見ても、そのフォーマットは次のようになります:

HEADER 
    magic number ("bplist") 
    file format version (currently "0?") 

OBJECT TABLE 
    variable-sized objects 

    Object Formats (marker byte followed by additional info in some cases) 
    null 0000 0000   // null object [v"1?"+ only] 
    bool 0000 1000   // false 
    bool 0000 1001   // true 
    url 0000 1100 string  // URL with no base URL, recursive encoding of URL string [v"1?"+ only] 
    url 0000 1101 base string // URL with base URL, recursive encoding of base URL, then recursive encoding of URL string [v"1?"+ only] 
    uuid 0000 1110   // 16-byte UUID [v"1?"+ only] 
    fill 0000 1111   // fill byte 
    int 0001 0nnn ...  // # of bytes is 2^nnn, big-endian bytes 
    real 0010 0nnn ...  // # of bytes is 2^nnn, big-endian bytes 
    date 0011 0011 ...  // 8 byte float follows, big-endian bytes 
    data 0100 nnnn [int] ... // nnnn is number of bytes unless 1111 then int count follows, followed by bytes 
    string 0101 nnnn [int] ... // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes 
    string 0110 nnnn [int] ... // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t 
    string 0111 nnnn [int] ... // UTF8 string, nnnn is # of chars, else 1111 then int count, then bytes [v"1?"+ only] 
    uid 1000 nnnn ...  // nnnn+1 is # of bytes 
     1001 xxxx   // unused 
    array 1010 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows 
    ordset 1011 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only] 
    set 1100 nnnn [int] objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only] 
    dict 1101 nnnn [int] keyref* objref* // nnnn is count, unless '1111', then int count follows 
     1110 xxxx   // unused 
     1111 xxxx   // unused 

OFFSET TABLE 
    list of ints, byte size of which is given in trailer 
    -- these are the byte offsets into the file 
    -- number of these is in the trailer 

TRAILER 
    byte size of offset ints in offset table 
    byte size of object refs in arrays and dicts 
    number of offsets in offset table (also is number of objects) 
    element # in offset table which is top level object 
    offset table offset