首页 > 解决方案 > 通过 python 从大 zip 中提取特定文件

问题描述

我有一个包含所有目录和子目录的 300.000 多个文件的大 zip 另一方面,我有一个需要从 zip 中提取的 1200 个文件的列表。此列表将 dir 路径和文件名作为一个(参见 exp) exp:/var/db/bla/file.ext

此时,我使用以下代码从 zip 中搜索并提取文件(保留时间戳)。它有效,但它真的很慢。有没有更好的办法?现在它正在读取 zip 中的所有文件,如果匹配,它会提取它。有没有办法直接给出文件位置(通过列表)并提取它而不列出其中的所有文件?

files = df2.drop_duplicates().drop_duplicates().values.tolist()
pbar_max = (len(files))
pbar = tqdm(total=int(pbar_max))

##
for count, i in enumerate(files):

    for item in (f for f in zip_file.filelist if i in f.filename):

        e = item.date_time
        gettime = "%s/%s/%s %s:%s" % (e[0], e[1], e[2], e[3], e[4])

        #print(item.filename)
        zip_file.extract(item.filename, directory)
        filep = directory + item.filename
        timearry = time.mktime(time.strptime(gettime, '%Y/%m/%d %H:%M'))
        os.utime(filep, (timearry, timearry))

        pbar.update(1)



pbar.close()

希望有人有一个聪明的想法,谢谢

标签: python-3.xzip

解决方案


您的脚本很可能大部分时间都花在 中zip_file.extract,因此您可能无能为力。您需要通过探查器运行脚本才能确定。

也就是说,您可以通过重组两个循环来使事情变得更好。目前,您的外循环正在迭代zip_file.filelist1600 次。外部循环可以完全消除,像这样

# store the file list as a set
files = set( df2.drop_duplicates().drop_duplicates().values.tolist() )

# now only have to iterate the zip once
for item in (f for f in zip_file.zipinfo if f.filename in files):
    e = item.date_time
    gettime = "%s/%s/%s %s:%s" % (e[0], e[1], e[2], e[3], e[4])

    #print(item.filename)
    zip_file.extract(item.filename, directory)
    filep = directory + item.filename
    timearry = time.mktime(time.strptime(gettime, '%Y/%m/%d %H:%M'))
    os.utime(filep, (timearry, timearry))

    pbar.update(1)

您将需要测试代码以查看这是否有很大的不同。

[编辑]

这是一个工作示例

首先创建一个zip文件

$ touch alpha beta gamma delta
$ zip test.zip alpha beta gamma delta
updating: alpha (stored 0%)
updating: beta (stored 0%)
updating: gamma (stored 0%)
updating: delta (stored 0%)

现在浏览 zip 文件

import zipfile

# want to match against these three names
files = { 'alpha', 'gamma', 'omega' }

with zipfile.ZipFile('test.zip') as zip_file:
    for item in (f for f in zip_file.filelist if f.filename in files):
        print(item.filename)

输出

alpha
gamma

请注意,这仅在您知道匹配的 zip 文件中的确切文件名时才有效。您的代码正在进行子字符串匹配。


推荐阅读