【问题标题】:Concatenate gzipped files with Python, on Windows在 Windows 上使用 Python 连接 gzip 文件
【发布时间】:2013-08-13 12:18:44
【问题描述】:

有没有一种节省内存的方法可以在 Windows 上使用 Python 连接 gzip 压缩文件,而无需解压缩它们?

根据this answer的评论,应该很简单:

cat file1.gz file2.gz file3.gz > allfiles.gz

但是如何在 Windows 上使用 Python 执行此操作?

【问题讨论】:

    标签: python gzip concatenation


    【解决方案1】:

    如果

    cat file1.gz file2.gz file3.gz > allfiles.gz
    

    有效,那么这也应该有效:

    fileList = ['file1.gz', 'file2.gz', 'file3.gz']
    destFilename = 'allfiles.gz'
    
    bufferSize = 8  # Adjust this according to how "memory efficient" you need the program to be.
    
    with open(destFilename, 'wb') as destFile:
        for fileName in fileList:
            with open(fileName, 'rb') as sourceFile:
                chunk = True
                while chunk:
                    chunk = sourceFile.read(bufferSize)
                    destFile.write(chunk)
    

    【讨论】:

    • 这会将输入文件截断为缓冲区的大小。
    • 哎呀,你是对的 - 忘记了获取整个文件的 while 循环 - 已编辑,谢谢。
    • 内循环可以缩短为for chunk in iter(lambda: sourceFile.read(bufferSize), ''): destFile.write(chunk)。另外,请记住 PEP 8 推荐 names_with_underscores 优先于 camelCase。
    【解决方案2】:

    继续写入同一个文件。

    with open(..., 'wb') as wfp:
      for fn in filenames:
        with open(fn, 'rb') as rfp:
          shutil.copyfileobj(rfp, wfp)
    

    【讨论】:

      【解决方案3】:

      您不需要 python 将许多文件复制到一个。您可以为此使用标准的 Windows“复制”:

      copy file1.gz /b + file2.gz /b + file3.gz /b allfiles.gz
      

      或者,简单地说:

      copy *.gz /b allfiles.gz
      

      但是,如果您想使用 Python,Ignacio 的答案是更好的选择。

      【讨论】:

      • 您忘记了+s 和/bs。
      • 您在allfiles.gz 之前有一个无关的+,这将导致file1.gz 被覆盖。 “如果省略 Destination,文件将合并并存储在列表中第一个文件的名称下。” source
      • 你是对的。感谢您对细节的关注。比说,要理解文件前后/b的意思真的很难理解..
      【解决方案4】:

      幸运的是,gzip 压缩文件可以通过cat CL 命令直接连接,但不幸的是,似乎没有明显的 python 命令来执行此操作(无论如何在标准库 gzip 中)。然而,我只是简单地看了看。可能有一些图书馆可以做到这一点。

      不过,使用标准库实现此目的的一种方法是使用 subprocess 调用 cat

      from subprocess import check_call
      command = "cat {} {} > {}".format(file1_path, file2_path, output_name)
      check_call(command.split())  # Check call takes a list
      

      要将其推广到任意数量的输入,您可以这样做:

      inputs = ['input1', 'input2', ... 'input9001']
      output_name = 'output.gz'
      
      command = "".join(['cat ', '{} ' * len(inputs), '> {out}'])
      _call_ = command.format(*inputs, out=output_name).split()
      
      check_call(_call_)
      

      我希望这对某人有帮助。

      【讨论】:

        猜你喜欢
        • 2018-10-03
        • 1970-01-01
        • 2017-04-10
        • 2022-08-08
        • 2011-12-30
        • 1970-01-01
        • 2014-11-17
        • 1970-01-01
        • 2013-12-07
        相关资源
        最近更新 更多