【问题标题】:How to compress a large file in Python?如何在 Python 中压缩一个大文件?
【发布时间】:2016-06-26 15:00:11
【问题描述】:

我遇到的问题是存储文件的名称。存储的文件未使用原始/未压缩文件名命名。相反,存储的文件以存档名称命名(带有附加的“.gz”扩展名)。

预期结果:
file.txt.gz {档案名称}
....file.txt {存储的文件名}

实际结果:
file.txt.gz {档案名称}
....file.txt.gz {存储的文件名}

通读 gzip 文档 (https://docs.python.org/2.7/library/gzip.html) 示例代码:

import gzip
import shutil
with open('file.txt', 'rb') as f_in, gzip.open('file.txt.gz', 'wb') as f_out:
    shutil.copyfileobj(f_in, f_out)

如何让存档存储名为“file.txt”而不是“file.txt.gz”的文件?

【问题讨论】:

  • 所以你想将压缩文件存储在file.txt中?即覆盖现有文件?
  • 但是现在环顾四周,不要以为gzip是真正的归档格式,只是文件压缩-_-
  • 再想一想:我尝试了代码,它工作正常,文件名正确存储在存档(“file.txt”)中。
  • @Jake 最好了解更多关于实际使用哪个 python 版本以及如何解压缩文件,因为我的对应于引用的文档链接,所以如果有一个不太可能的问题具体到 2.7(但我们没有太多线索)。
  • 是的,这不是gzip 模块应该的工作方式。要么你发现了一个老错误,要么存在误解,要么代码中发生了一些有趣的事情。

标签: python compression gzip


【解决方案1】:

你必须使用gzip.GzipFile();速记 gzip.open() 不会做你想做的事。

Qthe doc:

fileobj 不是None 时,filename 参数仅用于包含在 gzip 文件头中,其中可能包含未压缩文件的原始文件名。如果可识别,它默认为 fileobj 的文件名;否则,它默认为空字符串,在这种情况下,原始文件名不包含在标题中。

试试这个:

import gzip
import shutil
with open('file.txt', 'rb') as f_in:
    with open('file.txt.gz', 'wb') as f_out:
        with gzip.GzipFile('file.txt', 'wb', fileobj=f_out) as f_out:
            shutil.copyfileobj(f_in, f_out)

【讨论】:

    【解决方案2】:

    您在区分“存储的文件名”和“存档名称”,但对于 gzip 压缩,这是错误的想法,因为 gzip 不是存档格式,而只是一种压缩协议。

    当您存储“gzip”文件时,它不会(必然)记住原始文件名。只有原始文件的压缩内容,你可以给它任何你想要的名字。有一个约定,将其命名为与原始文件相同的名称,但附加“.gz”。如果您只提供文件名,则 Unix 系统上的“gzip”和“gunzip”实用程序将假定:

    gzip foo.txt
    # now foo.txt has been deleted, and foo.txt.gz exists
    gunzip foo.txt.gz
    # now you have foo.txt back, and foo.txt.gz has been deleted.
    

    如果您将 foo.txt.gz 重命名为 bar.txt.gz,然后使用 gunzip,如果您使用 Unix gunzip,您将获得“goo.txt”(但其他实用程序可能会有所不同)。

    但是,您可以在流模式下使用 gzip 和 gunzip,在这种情况下,它们对文件名一无所知 - gzip 真正用于压缩,而不关心文件名。

    (编辑:gzip可以存储文件名,但在某些情况下不能(如果没有原始“文件”,只有数据),并且在解压缩时是否使用它是完全可选的)。

    【讨论】:

    • 我认为这是不正确的。文件名很可能存储在 Wikipedia 上提到的 gzip 文件头中。尝试实际重命名一个 gzip 文件,然后解压缩它 - 您将使用以前的原始名称取回文件。或者至少我可以用我安装的软件找回它。
    • @brezniczky 通过修改是正确的,“未压缩名称”源自与 gzip.open 一起使用的文件名。如果您打开文件foo.txt.gz,则标题中未压缩的名称将为foo.txt,即使源文件可能称为bar.txt。有关逻辑,请参阅gzip module source
    • 你说得对,我没有意识到 gzip 确实存储了原始文件名。 Unix gunzip 解压时不使用这个,除非你传递“-N”,这不是默认的,所以不能依赖。 Python 模块可能会做其他事情,但一般来说,gzip 应该被视为一种数据压缩格式,而不是存档格式。
    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 2022-07-06
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    相关资源
    最近更新 更多