使用Pylzma与流媒体和7Zip兼容

时间:2014-05-15 23:51:36

标签: python 7zip

我一直在使用pylzma,但我必须能够创建与7zip windows应用程序兼容的文件。需要注意的是,我的一些文件非常大(由专有二进制格式的第三方软件创建的3到4GB)。

我在这里和这里的说明一遍又一遍:https://github.com/fancycode/pylzma/blob/master/doc/USAGE.md

我可以使用以下代码创建兼容文件:

def Compacts(folder,f):
  os.chdir(folder)
  fsize=os.stat(f).st_size
  t=time.clock()
  i = open(f, 'rb')
  o = open(f+'.7z', 'wb')
  i.seek(0)

  s = pylzma.compressfile(i)
  result = s.read(5)
  result += struct.pack('<Q', fsize)
  s=result+s.read()
  o.write(s)
  o.flush()
  o.close()
  i.close()
  os.remove(f)

较小的文件(最高2Gb)使用此代码可以很好地压缩,并且与7Zip兼容,但是较大的文件在一段时间后才会崩溃。

根据用户指南,要压缩大文件,应该使用流式传输,但是生成的文件与7zip不兼容,如下面的代码段所示。

def Compacts(folder,f):
  os.chdir(folder)
  fsize=os.stat(f).st_size
  t=time.clock()
  i = open(f, 'rb')
  o = open(f+'.7z', 'wb')
  i.seek(0)

  s = pylzma.compressfile(i)
  while True:
    tmp = s.read(1)
    if not tmp: break
    o.write(tmp)
  o.flush()
  o.close()
  i.close()
  os.remove(f)

关于如何在保持7zip兼容性的同时合并pylzma中存在的流技术的任何想法?

1 个答案:

答案 0 :(得分:2)

您仍需要正确编写标题(.read(5))和大小,例如像这样:

import os
import struct

import pylzma

def sevenzip(infile, outfile):
    size = os.stat(infile).st_size
    with open(infile, "rb") as ip, open(outfile, "wb") as op:
        s = pylzma.compressfile(ip)
        op.write(s.read(5))
        op.write(struct.pack('<Q', size))
        while True:
            # Read 128K chunks.
            # Not sure if this has to be 1 instead to trigger streaming in pylzma...
            tmp = s.read(1<<17)
            if not tmp:
                break
            op.write(tmp)

if __name__ == "__main__":
    import sys
    try:
        _, infile, outfile = sys.argv
    except:
        infile, outfile = __file__, __file__ + u".7z"

    sevenzip(infile, outfile)
    print("compressed {} to {}".format(infile, outfile))