跳转到主要内容

透明打开压缩文件

项目描述

https://img.shields.io/pypi/v/xopen.svg?branch=main

xopen

此Python模块提供了一个名为 xopen 的函数,它类似于Python内置的 open 函数,但还可以透明地处理压缩文件。xopen 选择读取或写入压缩文件的最有效方法。

支持的压缩格式包括

  • gzip (.gz)

  • bzip2 (.bz2)

  • xz (.xz)

  • Zstandard (.zst)(可选)

xopen 与Python 3.8及更高版本兼容。

示例用法

打开文件以读取

from xopen import xopen

with xopen("file.txt.gz") as f:
    content = f.read()

以二进制模式写入文件,设置压缩级别,并避免使用外部进程

from xopen import xopen

with xopen("file.txt.xz", mode="wb", threads=0, compresslevel=3) as f:
    f.write(b"Hello")

xopen 函数

xopen 模块提供了一个名为 xopen 的单一函数,其签名如下

xopen(
  filename: str | bytes | os.PathLike,
  mode: Literal["r", "w", "a", "rt", "rb", "wt", "wb", "at", "ab"] = "r",
  compresslevel: Optional[int] = None,
  threads: Optional[int] = None,
  *,
  encoding: str = "utf-8",
  errors: Optional[str] = None,
  newline: Optional[str] = None,
  format: Optional[str] = None,
) -> IO

该函数使用适合检测到的文件格式的函数打开文件,并返回一个类似打开文件的对象。

在编写时,文件格式是根据文件扩展名选择的:.gz.bz2.xz.zst。这可以通过format来覆盖。如果扩展名不被识别,则不使用压缩。

在读取时,如果文件名扩展名可用,格式从扩展名中检测。在读取时没有文件名扩展名,格式从文件签名https://zh.wikipedia.org/wiki/文件格式#魔数)中检测。

参数

filename(str、bytes或os.PathLike):要打开的文件的名称。

如果设置为"-",则返回标准输出(在模式"w"中)或标准输入(在模式"r"中)。

modeencodingerrorsnewline:这些参数与Python内置的open函数的意义相同,只是默认编码总是UTF-8而不是首选的区域设置编码。encodingerrorsnewline仅在以文本模式打开文件时使用。

compresslevel:写入gzip、xz和Zstandard文件的压缩级别。如果设置为None,则使用默认值,取决于格式:gzip:1,xz:6,Zstandard:3。

此参数对于其他压缩格式将被忽略。

format:覆盖自动检测的输入或输出格式。可能的值是:"gz""xz""bz2""zst"

threads:设置用于压缩或解压缩的额外线程数。如果后端不支持线程,则可能被忽略。

如果threads为None(默认值),则使用尽可能多的CPU核心,但不超过四个。

xopen尝试将(解)压缩卸载到其他线程,以释放主Python线程供应用程序使用。这可以通过使用子进程到外部应用程序或使用支持线程的库来完成。

将线程数设置为0,以强制xopen只使用主Python线程。

后端

gzip文件的打开委托给以下程序或库之一

对于xz文件,使用到xz程序的管道,因为它内置了多线程压缩支持。

对于bz2文件,使用pbzip2(并行bzip2)

如果以上方法都不可用,xopen将回退到Python内置函数(gzip.openlzma.openbz2.open)。

可重现性

xopen以可重现的方式写入gzip文件。

通常,gzip文件包含文件头中的时间戳,这意味着在不同时间压缩相同的数据将产生不同的输出文件。xopen禁用了所有支持的gzip压缩后端。例如,当使用外部进程时,它设置命令行选项--no-name(等同于-n)。

请注意,不同的gzip压缩后端通常不会产生相同的输出,因此当执行环境从一次xopen()调用更改为下一次时,可重现性可能不再保证。这包括CPU架构,因为igzip会根据它调整其算法

bzip2和xz压缩方法不将时间戳存储在文件头中,因此它们的输出也可以重现。

可选的Zstandard支持

对于读取和写入Zstandard (.zst)文件,需要安装zstd命令行程序或Python的zstandard包。

  • 如果xopen()threads参数为None(默认)或任何大于0的值,xopen将使用外部zstd进程。

  • 如果上述操作失败(因为没有可用的zstd程序)或如果threads为0,则使用zstandard包。

为确保您获得正确的zstandard版本,您可以指定xopenzstd扩展,即使用pip install xopen[zstd]进行安装。

更新日志

v2.0.2 (2024-06-12)

  • #161: 修复了读取大型压缩文件时外部程序触发的错误。

v2.0.1 (2024-03-28)

  • #158: 修复了从stdin和其他管道读取时丢弃输入的第一个字节的问题。

  • #156: 现在可以打开使用--long=31压缩的Zstd文件而不会引发错误。

v2.0.0 (2024-03-26)

  • #154: 使gzip级别的支持更加一致。支持0-9级别。当存在pigz后端时才可用的11级不再受支持。当使用作为后端的gzip应用程序后端时,不进行压缩的gzip格式0级会导致崩溃,因为该后端没有-0标志。xopen()现在在这种情况下将取决于其他后端。

  • #152: xopen()现在接受类似文件的对象作为其文件名参数。

  • #146, #147, #148: 对代码大小和可读性进行了各种重构。

    • PipedCompressionReader/Writer现在合并为_PipedCompressionProgram类。

    • _PipedCompressionProgram是二进制文件。对于文本读取和写入,在xopen()函数中使用io.TextIOWrapper进行包装。

    • 已删除从PipedCompressionReader/Writer派生的类。

  • #148: xopen的与管道读取和写入相关的类、变量和函数全部通过前缀下划线变为私有。这些不是API的一部分,并且可能在版本之间发生变化。

v1.9.0 (2024-01-31)

  • #142: 现在python-isal压缩后端仅用于1和2压缩级别。与其他后端不同,python-isal的0级在gzip格式中提供了压缩数据而不是未压缩数据。python-isal的3级没有比2级更好的压缩效果。

  • #140: PipedCompressionReader/Writer现在从io.IOBase抽象类派生。

  • #138: 当调用函数没有提供值时,gzip的默认压缩级别现在是1。默认值以前由后端确定。

  • #135: xopen现在在适用的情况下使用zlib-ng。

  • 编号133:已不再使用igzip作为(解)压缩后端,因为在所有用例中,python-isal的线程模式都是更好的选择。

版本1.8.0(2023-11-03)

  • 编号131:xopen现在在适用情况下会委托给isal.igzip_threaded模块,而不是将数据通过管道传输到外部程序。这使得使用线程读写gzip文件更加高效。

  • 不再支持Python 3.7,并添加了对Python 3.12的支持。

版本1.7.0(2022-11-03)

  • 编号91:增加了对Zstandard(.zst)文件的可选支持。这需要安装Python的zstandard包或者确保zstd命令行程序可用。

版本1.6.0(2022-08-10)

  • 编号94:在写入gzip文件时,省略原始文件的日期和时间戳(等同于在命令行中使用gzip --no-name(或-n))。这允许以可重复的方式写入文件。

版本1.5.0(2022-03-23)

  • 编号100:不再支持Python 3.6。

  • 编号101:添加了对从外部xz进程进行管道传输的支持。由@fanninpm贡献。

  • 编号102:支持设置xz压缩级别。由@tsibley贡献。

版本1.4.0(2022-01-14)

  • PipedCompressionReader类添加了seek()tell()方法(以支持Windows兼容性)

版本1.3.0(2022-01-10)

  • xopen现在在Windows上可用(除了Linux和macOS)。

  • 为了与内置的open()函数有更好的兼容性,xopen()增加了encodingerrorsnewlines参数,这些参数的含义与open()中相同。然而,与内置的open()不同,编码默认为UTF-8。

  • 增加了一个format参数,允许强制指定压缩文件格式。

版本1.2.0(2021-09-21)

  • pbzip2现在在threads大于零时用于打开.bz2文件(由@DriesSchaumont贡献)。

版本1.1.0(2021-01-20)

  • 不再支持Python 3.5。

  • 在Linux系统上,现在将python-isal添加为必需依赖项。当不使用外部进程时,这将显著加快gzip文件的读取速度。

版本1.0.0(2020-11-05)

  • 如果已安装,则程序igzip(Intel ISA-L的一部分)现在用于在压缩级别1-3时读取和写入gzip压缩文件,这可以显著提高速度。

版本0.9.0(2020-04-02)

  • 编号80:当要打开读取的文件的文件名扩展名不可用时,将检查内容(如果可能)并用于确定适用的压缩格式(由@bvaisvil贡献)。

  • 本发行版不再支持Python 2.7和3.4。现在需要Python 3.5或更高版本。

版本0.8.4(2019-10-24)

  • 在读取gzip文件时,强制pigz只使用单个进程。实际上,pigz在解压缩时无法使用多个核心。默认情况下,它会使用额外的I/O进程,这略微减少了wall-clock时间,但增加了CPU时间。使用pigz的单核解压缩速度仍然比常规gzip快约两倍。

  • 允许threads=0来指定不应使用外部pigz/gzip进程(此时将使用常规的gzip.open())。

版本0.8.3(2019-10-18)

  • 编号20:在读取gzip文件时,默认让pigz最多使用四个线程。此限制以前仅适用于写入文件。由@bernt-matthias贡献。

  • 支持 Python 3.8

v0.8.0 (2019-08-14)

  • #14: 优化迭代压缩文件时的速度。

v0.6.0 (2019-05-23)

  • 在读取压缩文件时,xopen现在将使用一个pigz子进程。这比使用gzip.open更快。

  • 将在未来的某个版本中放弃Python 2支持。

v0.5.0 (2019-01-30)

  • 默认情况下,现在只允许pigz最多使用四个线程。这有望减少一些用户在同时打开许多文件时遇到的多线程问题。

  • xopen现在接受pathlib.Path对象。

v0.4.0 (2019-01-07)

  • 放弃Python 3.3支持

  • 添加一个threads参数(传递给pigz

v0.3.2 (2017-11-22)

  • #6: 通过使用外部bz2file库使多块bz2在Python 2上工作。

v0.3.1 (2017-11-22)

  • 放弃Python 2.6支持

  • #5: 修复PipedGzipReader.read()不返回任何内容的问题

v0.3.0 (2017-11-15)

  • 添加gzip压缩参数

v0.2.1 (2017-05-31)

  • #3: 尽可能允许向bz2和lzma文件追加内容

v0.1.1 (2016-12-02)

  • 修复一个死锁问题

v0.1.0 (2016-09-09)

  • 初始发布

致谢

xopen这个名称来源于BWA中相同名称的C函数,该函数包含在utils.h文件中

一些想法来自canopener项目。如果您也想打开S3文件,您可能需要使用该模块。

@kyleabeauchamp在创建此存储库之前贡献了对文件追加的支持。

维护者

项目详情


下载文件

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

源代码分发

xopen-2.0.2.tar.gz (32.2 kB 查看散列值)

上传时间 源代码

构建分发

xopen-2.0.2-py3-none-any.whl (17.1 kB 查看散列值)

上传于 Python 3

由...

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