监视python中的zip文件提取(显示百分比)

时间:2013-07-28 23:15:58

标签: python

我在一个目录中有一百个zipfiles,所以我做了一个python脚本来解压缩所有文件,但是我需要在任何一个巨大的zipfile中显示每个文件的百分比状态(实际上每个zipfile只有一个文件)。 / p>

我在这里找到了一些例子,但是在所有这些例子中,每个zipfile里面都有几个文件,因此百分比是关于zipfile里面的文件数而不是其中一个(我的情况)。

所以,我编写了下面的代码,但对于每个zipfile,我只是显示“100%完成”,但我应该为每个文件显示,类似的东西:

10%完成 12%完成 16%完成 ... 100%完成

我真的很感激任何建议。

# -- coding: utf-8 --

import glob, zipfile, sys, threading
from os.path import getsize

class Extract(threading.Thread):
      def __init__(self, z, fname, base, lock):
          threading.Thread.__init__(self)
          self.z = z
          self.fname = fname
          self.base = base
          self.lock = lock

      def run(self):
          self.lock.acquire()
          self.z.extract(self.fname, self.base)
          self.lock.release()

if len(sys.argv) < 2:
   sys.exit("""
Sintaxe : python %s [Nome da Pasta]
""" % sys.argv[0])

base = sys.argv[1]
if base[len(base)-1:] != '/':
   base += '/'

for fs in glob.glob(base + '*.zip'):
    if 'BR' not in fs.split('.'):
       f = open(fs,'rb')
       z = zipfile.ZipFile(f)
       for fname in z.namelist():
           size = [s.file_size for s in z.infolist() if s.filename == fname][0]
           lock = threading.Lock()
           background = Extract(z, fname, base, lock)
           background.start()
           print fname + ' => ' + str(size)
           while True:
                 lock.acquire()
                 filesize = getsize(base + fname)
                 lock.release()
                 print "%s %% completed\r" % str(filesize * 100.0 / size)
                 if filesize == size:
                    break

2 个答案:

答案 0 :(得分:0)

The extract method直接写入磁盘。没关系,但是你想要加入其中。您可能希望使用open,而不是使用extract。使用open,您将获得一个类似文件的对象,您可以从该文件复制到磁盘上的文件,随时写出进度。

答案 1 :(得分:0)

以下是您可以用来修改自己的代码片段。它使用ZipInfo object来查找成员文件的未压缩大小。当你读出它时,你可以报告你的完成程度。

请注意,这是为Python 3.2及更高版本编写的;然后添加了with语句支持。使用以前的版本,您需要打开zip文件并手动关闭它。

from zipfile import ZipFile

chunk_size = 1024 * 1024
zip_path = "test_zip.zip"
with ZipFile(zip_path, 'r') as infile:
    for member_info in infile.infolist():
        filename = member_info.filename
        file_size = member_info.file_size
        with open("{}_{}".format(zip_path, filename), 'wb') as outfile:
            member_fd = infile.open(filename)
            total_bytes = 0
            while 1:
                x = member_fd.read(chunk_size)
                if not x:
                    break
                total_bytes +=outfile.write(x)
                print("{0}% completed".format(100 * total_bytes / file_size))