簡體   English   中英

如何打印壓縮文件python的百分比

[英]How to print the percentage of zipping a file python

我希望在壓縮文件的同時獲得文件的百分比。 例如,它將打印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()

遺憾的是,您無法從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()來構造存檔路徑名。


順便說一句,在你的代碼中,你的內部for循環中有str(pic) 通常,在循環內使用常量參數重新評估函數是有點浪費的。 但在這種情況下,它完全是多余的,因為從你的第一個聲明看來, pic已經是一個字符串了。

現有的答案僅適用於文件級別,即如果您有一個巨大的壓縮文件,則在整個操作完成之前不會看到任何進度。 在我的情況下,我只有一個巨大的文件,我做了這樣的事情:

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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM