跳转到主要内容

支持随机访问的XZ文件格式的纯Python实现

项目描述

python-xz

支持随机访问的XZ文件格式的纯Python实现

利用lzma模块进行快速(解)压缩

GitHub build status Release on PyPI Code coverage Mypy type checker MIT License


📖 文档   |   📃 更新日志


一个XZ文件可以由多个流和块组成。这允许在读取时快速随机访问,但Python的内置lzma模块不支持这一点(它会读取所有之前的块而没有任何意义)。

lzma lzmaffi python-xz
模块类型 内置 cffi(C扩展) 纯Python
📄 读取
随机访问 ❌ 不支持1 ✔️ 支持2 ✔️ 支持2
多个块 ✔️ 支持 ✔️✔️ 支持3 ✔️✔️ 支持3
多个流 ✔️ 支持 ✔️ 支持 ✔️✔️ 支持4
流填充 ❌ 不支持5 ✔️ 支持 ✔️ 支持
📝 写入
w模式 ✔️ 支持 ✔️ 支持 ✔️ 支持
x模式 ✔️ 支持 ❌ 不支持 ✔️ 支持
a模式 ✔️ 新流 ✔️ 新流 ⏳ 计划中
r+/w+… 模式 ❌ 不支持 ❌ 不支持 ✔️ 支持
多个块 ❌ 不支持 ❌ 不支持 ✔️ 支持
多个流 ❌ 不支持6 ❌ 不支持6 ✔️ 支持
流填充 ❌ 不支持 ❌ 不支持 ⏳ 计划中
备注
  1. 从某个位置读取将从头开始读取文件
  2. 从某个位置读取将从块的开始读取文件
  3. 可以通过block_boundaries属性获取块位置
  4. 使用 stream_boundaries 属性提供的流位置
  5. 相关 问题
  6. 可以通过手动关闭并重新以追加模式打开来实现

安装

使用 pip 安装 python-xz

$ python -m pip install python-xz

还有一个非官方的 conda 包也可用,请参阅 conda-forge 的 python-xz,更多详细信息请见 问题 #5

用法

API 与 lzma 类似:您可以使用 xz.openxz.XZFile

读取模式

>>> with xz.open('example.xz') as fin:
...     fin.read(18)
...     fin.stream_boundaries  # 2 streams
...     fin.block_boundaries   # 4 blocks in first stream, 2 blocks in second stream
...     fin.seek(1000)
...     fin.read(31)
...
b'Hello, world! \xf0\x9f\x91\x8b'
[0, 2000]
[0, 500, 1000, 1500, 2000, 3000]
1000
b'\xe2\x9c\xa8 Random access is fast! \xf0\x9f\x9a\x80'

以文本模式打开同样有效,但请注意,seek 参数以及边界仍然以字节为单位(就像在 lzma.open 中一样)。

>>> with xz.open('example.xz', 'rt') as fin:
...     fin.read(15)
...     fin.stream_boundaries
...     fin.block_boundaries
...     fin.seek(1000)
...     fin.read(26)
...
'Hello, world! 👋'
[0, 2000]
[0, 500, 1000, 1500, 2000, 3000]
1000
'✨ Random access is fast! 🚀'

写入模式

仅支持从文件末尾写入。然而,首先截断文件是可能的。注意,截断仅在块边界上受支持。

>>> with xz.open('test.xz', 'w') as fout:
...     fout.write(b'Hello, world!\n')
...     fout.write(b'This sentence is still in the previous block\n')
...     fout.change_block()
...     fout.write(b'But this one is in its own!\n')
...
14
45
28

高级用法

  • r+/w+/x+ 之类的模式允许同时以读取和写入方式打开;然而,在当前实现中,当从其中读取数据时,正在写入的块将自动关闭。
  • checkpresetfilters 参数到 xz.openxz.XZFile 允许配置新流和块的默认值。
  • 使用 change_block 方法更改块(可以在之前更改 presetfilters 属性以应用于新块)。
  • 使用 change_stream 方法更改流(可以在之前更改 check 属性以应用于新流)。

常见问题解答(FAQ)

随机访问是如何工作的?

XZ 文件由多个流组成,每个流由多个块组成。这可以通过 xz --list 查看。

$ xz --list file.xz
Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename
    1      13     16.8 MiB    297.9 MiB  0.056  CRC64   file.xz

要从第 10 个块的中间读取数据,我们将从开始解压缩第 10 个块,直到达到中间(并丢弃解压缩的数据),然后从该点返回解压缩的数据。

选择合适的块大小是在随机访问的查找时间和压缩比之间进行权衡。

如何创建针对随机访问优化的 XZ 文件?

您可以打开文件进行写入,并使用 change_block 方法创建多个块。

其他工具也允许创建具有多个块的 XZ 文件

$ xz -T0 file                          # threading mode
$ xz --block-size 16M file             # same size for all blocks
$ xz --block-list 16M,32M,8M,42M file  # specific size for each block
  • PIXZ 默认创建具有多个块的文件
$ pixz file

Python 版本支持

作为一般规则,所有同时 发布并获得官方支持 的 Python 版本都由 python-xz 支持,并对(CPython 和 PyPy 实现进行测试)。

如果您有其他用例或发现某些 Python 版本存在问题,请随时 提交工单

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源分发

python-xz-0.5.0.tar.gz (70.5 kB 查看哈希值)

上传时间

构建分发

python_xz-0.5.0-py3-none-any.whl (20.2 kB 查看散列值)

上传时间: Python 3

支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面