我想在压缩文件的同时获取文件的百分比。例如,它将打印1%,2%,3%等。我不知道从哪里开始。我现在该如何做到这一点我只需要压缩文件的代码。
代码:
zipPath = zipfile.ZipFile("Files/Zip/" + pic + ".zip", "w")
for root, dirs, files in os.walk(filePath):
for file in files:
zipPath.write(os.path.join(root, file), str(pic) + "\\" + file)
print("Done")
zipPath.close()
答案 0 :(得分:2)
不幸的是,您无法从zipfile模块压缩每个单独的文件,但是您可以通过跟踪到目前为止已处理的字节数来了解总进度。
正如Mikko Ohtamaa建议的那样,最简单的方法是两次遍历文件列表,首先确定文件大小,然后再进行压缩。但是,正如Kevin提到的那样,目录的内容可能会在这两个传递之间发生变化,因此数字可能不准确。
下面的程序(为Python 2.6编写)说明了这个过程。
#!/usr/bin/env python
''' zip all the files in dirname into archive zipname
Use only the last path component in dirname as the
archive directory name for all files
Written by PM 2Ring 2015.02.15
From http://stackoverflow.com/q/28522669/4014959
'''
import sys
import os
import zipfile
def zipdir(zipname, dirname):
#Get total data size in bytes so we can report on progress
total = 0
for root, dirs, files in os.walk(dirname):
for fname in files:
path = os.path.join(root, fname)
total += os.path.getsize(path)
#Get the archive directory name
basename = os.path.basename(dirname)
z = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
#Current data byte count
current = 0
for root, dirs, files in os.walk(dirname):
for fname in files:
path = os.path.join(root, fname)
arcname = os.path.join(basename, fname)
percent = 100 * current / total
print '%3d%% %s' % (percent, path)
z.write(path, arcname)
current += os.path.getsize(path)
z.close()
def main():
if len(sys.argv) < 3:
print 'Usage: %s zipname dirname' % sys.argv[0]
exit(1)
zipname = sys.argv[1]
dirname = sys.argv[2]
zipdir(zipname, dirname)
if __name__ == '__main__':
main()
请注意,我使用zipfile.ZIP_DEFLATED
压缩参数打开zip文件;默认值为zipfile.ZIP_STORED
,即不执行压缩。此外,zip文件可以处理DOS样式和Unix样式的路径分隔符,因此您不需要在归档路径名中使用反斜杠,并且我的代码显示您只需使用os.path.join()
来构建存档路径名。
顺便说一句,在你的代码中,你的内部str(pic)
循环中有for
。通常,在循环内使用常量参数重新评估函数有点浪费。但在这种情况下,它完全是多余的,因为从你的第一个陈述来看,似乎pic
已经是一个字符串。
答案 1 :(得分:-1)
现有的答案仅适用于文件级别,即如果您有一个大型文件要压缩,则在整个操作完成之前不会看到任何进度。在我的情况下,我只有一个巨大的文件,我做了类似的事情:
import os
import types
import zipfile
from functools import partial
if __name__ == '__main__':
out_file = "out.bz2"
in_file = "/path/to/file/to/zip"
def progress(total_size, original_write, self, buf):
progress.bytes += len(buf)
progress.obytes += 1024 * 8 # Hardcoded in zipfile.write
print("{} bytes written".format(progress.bytes))
print("{} original bytes handled".format(progress.obytes))
print("{} % done".format(int(100 * progress.obytes / total_size)))
return original_write(buf)
progress.bytes = 0
progress.obytes = 0
with zipfile.ZipFile(out_file, 'w', compression=zipfile.ZIP_DEFLATED) as _zip:
# Replace original write() with a wrapper to track progress
_zip.fp.write = types.MethodType(partial(progress, os.path.getsize(in_file),
_zip.fp.write), _zip.fp)
_zip.write(in_file)
不是最佳的,因为每次调用write()时都会处理一个硬编码的字节数,这可能会改变。
此功能也经常被调用,可能不会为每次调用都更新UI。