【问题标题】:Finding the original filename when extracting gzip files in python在python中提取gzip文件时查找原始文件名
【发布时间】:2020-02-03 22:13:45
【问题描述】:

不久前,一位 YouTuber 发布了一个谜题,并要求他的社区解决它。我已经解决了这个难题,但我记得其中的一部分我一直想在 python 中自动化一个脚本。它基本上是一个随机归档 10000 多次的文件。有人编写了一个脚本,该脚本使用不同的归档方法一遍又一遍地随机归档文件。 (.zip、.rar、.jar、.tar.tar.gz、.gz 和 .7z)除了 .gz 文件之外,我已经能够完美地提取所有这些文件类型。使用tarfile 模块可以很好地提取tar.gz 文件,但显然无法提取普通的.gz 文件。我可以成功解压文件,但给我的只是原始字节数据。

这就是我想要做的:

我需要在 python 中提取一个普通的 .gz 文件(不是 tar.gz)的内容,就像我打开七个 zip 并使用它们的 GUI 提取一样。

有几点要提:

  1. .gz 文件可以在 7 个 zip 中正常打开。我可以查看内容并将其解压缩,就像它们是普通的 .zip 文件一样。

  2. 我需要存档项目的原始文件名。我设法从其中一个 .gz 文件中提取了一个 .zip,但它只有在我这样做时才有效:

     from gzip import open as gzopen
     with gzopen(file_name, 'rb') as f_in:
         with open('file.zip', 'wb') as f_out:
            copyfileobj(f_in, f_out)
    

    这样做的问题是它总是将 .gz 解压缩为 file.zip,即使存档的实际文件是 .7z 或 .rar。我需要它来正确识别扩展类型并正确命名。

【问题讨论】:

  • 嗯?为什么要使用任何扩展名来命名输出文件,而不是在原始文件名末尾删除.gz 之后留下的任何内容?没有理智的人会 gzip 压缩文件,因此添加 .zip 扩展名是没有意义的。
  • ...也就是说,如果一个文件是foo.txt.gz,你的输出应该只是命名为foo.txt;如果是bar.doc.gz,则输出应该是bar.doc,等等。压缩器而不是归档器的全部意义是它只包含一个文件;如果它的命名正确(按照惯例),那么该文件应该只是剥离压缩器扩展名。
  • ...如果您的输出名称与它们的类型不符,则处理它们的方式与处理名为foo 的文件完全相同,根本没有扩展名。 (执行此操作的常规方法涉及 libmagic,该库支持 UNIX 上的 file 命令;这在某些方面并不完美,但此处超出了完整的讨论范围)。
  • 问题是在某些情况下文件只是命名为file.gz
  • 是的,但是如果你有一个名为 file 的东西,你就会回到同一个地方,并且同样的修复适用。没有任何关于 gzip 独有的问题或其解决方案的问题(除非填写了带有原始文件名的 gzip 标头,但由于这是一个可选字段,我不会打赌它;即使它存在在你的一些数据中,如果你使用它,你需要编写在它不存在时可以正常工作的代码,以获得一个健壮的解决方案)。

标签: python python-3.x gzip


【解决方案1】:

GZIP 算法不压缩文件,它压缩字节。当然,文件也可以看作是字节流,但文件还有很多其他属性(名称、所有者、日期、权限等)。原始字节流缺少所有这些。

因此,如果gzip 作为可执行文件压缩文件,它只会压缩文件的内容,并保持其他所有内容(所有者、日期等)不变。除了名称:它附加了一个.gz 后缀。

所以,如果您想知道文件的原始名称,只需去掉.gz 后缀即可。

当然,gzip 也可以用于压缩其他流,例如用户输入或命令的输出。如果它手头没有文件,它会将压缩的字节流定向到标准输出,从那里它可以再次重定向到某个文件。而且这个文件可以再次有后缀.gz(并且经常有)。因此,名称以.gz 结尾的文件不一定是该名称没有.gz 后缀的文件的压缩版本。

后缀的某些组合经常被缩写,例如.tar.gz 通常被命名为 .tgz

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多