支持随机访问的XZ文件格式的纯Python实现
项目描述
一个XZ文件可以由多个流和块组成。这允许在读取时快速随机访问,但Python的内置lzma
模块不支持这一点(它会读取所有之前的块而没有任何意义)。
lzma | lzmaffi | python-xz | |
---|---|---|---|
模块类型 | 内置 | cffi(C扩展) | 纯Python |
📄 读取 | |||
随机访问 | ❌ 不支持1 | ✔️ 支持2 | ✔️ 支持2 |
多个块 | ✔️ 支持 | ✔️✔️ 支持3 | ✔️✔️ 支持3 |
多个流 | ✔️ 支持 | ✔️ 支持 | ✔️✔️ 支持4 |
流填充 | ❌ 不支持5 | ✔️ 支持 | ✔️ 支持 |
📝 写入 | |||
w 模式 |
✔️ 支持 | ✔️ 支持 | ✔️ 支持 |
x 模式 |
✔️ 支持 | ❌ 不支持 | ✔️ 支持 |
a 模式 |
✔️ 新流 | ✔️ 新流 | ⏳ 计划中 |
r+ /w+ … 模式 |
❌ 不支持 | ❌ 不支持 | ✔️ 支持 |
多个块 | ❌ 不支持 | ❌ 不支持 | ✔️ 支持 |
多个流 | ❌ 不支持6 | ❌ 不支持6 | ✔️ 支持 |
流填充 | ❌ 不支持 | ❌ 不支持 | ⏳ 计划中 |
备注
- 从某个位置读取将从头开始读取文件
- 从某个位置读取将从块的开始读取文件
- 可以通过
block_boundaries
属性获取块位置 - 使用
stream_boundaries
属性提供的流位置 - 相关 问题
- 可以通过手动关闭并重新以追加模式打开来实现
安装
使用 pip 安装 python-xz
$ python -m pip install python-xz
还有一个非官方的 conda 包也可用,请参阅 conda-forge 的 python-xz,更多详细信息请见 问题 #5。
用法
API 与 lzma 类似:您可以使用 xz.open
或 xz.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+
之类的模式允许同时以读取和写入方式打开;然而,在当前实现中,当从其中读取数据时,正在写入的块将自动关闭。 check
、preset
和filters
参数到xz.open
和xz.XZFile
允许配置新流和块的默认值。- 使用
change_block
方法更改块(可以在之前更改preset
和filters
属性以应用于新块)。 - 使用
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 Utils 需要使用标志来调用
$ 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-xz-0.5.0.tar.gz 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | a188f0436e811455f1bda61dce9dbe6f0fc1430334bff9f5afd0e668bb354774 |
|
MD5 | 3ca8e737f10ca542eaa7d17377860518 |
|
BLAKE2b-256 | 2a530eb6460a6854483271e0f67c4b680d02b6486056c3d597ceda224ee3cee7 |
关闭
python_xz-0.5.0-py3-none-any.whl 的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | b32a3fa2653cf92c4088b10827995c5ab2c3a74319e5e54c143e3e914a24385f |
|
MD5 | ff01c2a115c5c2bf95f3d09a272c0a94 |
|
BLAKE2b-256 | b4cd9c8cb6ad5431ba565f0ae39372cf745c047263c99654baba2781d4885edc |