使用 Python 读取二进制 Plist 文件

Posted

技术标签:

【中文标题】使用 Python 读取二进制 Plist 文件【英文标题】:Reading Binary Plist files with Python 【发布时间】:2012-01-13 19:21:40 【问题描述】:

我目前正在使用 Plistlib 模块来读取 Plist 文件,但我目前在处理二进制 Plist 文件时遇到了问题。

我想将数据读入一个字符串,以便稍后进行分析/打印等。我想知道他们是否在不使用 plutil 函数并将二进制文件转换为 XML 的情况下读取二进制 Plist 文件?

提前感谢您的帮助和时间。

【问题讨论】:

Python module for binary plist的可能重复 谢谢 Janne,我已经看过这篇文章,但我希望有人知道在不安装单独模块的情况下执行上述操作的方法,而只需使用 Python 中可用的预安装模块。 名为 plistlib 的默认模块不处理二进制 plist 文件。您最好选择“biplist”或其他第三个模块。 【参考方案1】:

虽然您没有指定 plutil,但它的工作解决方案可能对其他人有用,因为它已预安装在 Mac 上:

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)

【讨论】:

如果你给这个函数提供足够大的输入,它会卡在 p.stdin.write(content) 上。请阅读文档。【参考方案2】:

Biplist https://github.com/wooster/biplist 可通过简易安装或 pip 获得。

【讨论】:

【参考方案3】:

您可以使用工具 plutil(来自 http://www.libimobiledevice.org/ 的 libplist)将二进制文件转换为 xml plist 文件(反之亦然)。

【讨论】:

【参考方案4】:

我可能迟到了 10 年才能回答这个问题,但对于任何正在寻找这个问题的人来说,plistlib 就是你要找的。​​p>

【讨论】:

【参考方案5】:

您可以查看CFBinaryPList.c 源文件以了解它是如何在 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

【讨论】:

以上是关于使用 Python 读取二进制 Plist 文件的主要内容,如果未能解决你的问题,请参考以下文章

二进制plist结构

Python3读取大文件的方法

iOS项目开发实战——学会使用TableView列表控件plist读取与Section显示

初学python,小记二

在python中如何从二进制文件中读取信息

读取在线托管的 .plist 文件