使用os.walk提取压缩文件并避免递归提取

作为一名合格的技术员,在要=使用os.walk来提取压缩文件并避免递归提取,我们可以在遍历文件时检查文件的扩展名,并且只处理压缩文件而非目录。下面是一个示例代码,展示了如何使用os.walk来实现这一功能,并且避免了递归提取。具体的问题下面可以跟着我一起来看看,具体需要的参数以及问题我会一一详细的解答。

使用os.walk提取压缩文件并避免递归提取_第1张图片

问题背景

在使用 Python 编写递归提取器时,经常会遇到递归提取过多,导致性能降低的问题。在以下代码中,extractRecursive 函数通过 os.walk 遍历指定路径下的所有文件和目录,并使用 magic 模块来识别文件类型。当遇到压缩文件时,会调用 arcExtract 函数来解压该文件。但是,extractRecursive 函数在解压完成后还会再次调用自身,导致递归提取过多。

import os, magic
m = magic.open( magic.MAGIC_NONE )
m.load()

archive_type = [ 'gzip compressed data',
        '7-zip archive data',
        'Zip archive data',
        'bzip2 compressed data',
        'tar archive',
        'POSIX tar archive',
        'POSIX tar archive (GNU)',
        'RAR archive data',
        'Microsoft Outlook email folder (>=2003)',
        'Microsoft Outlook email folder']

def extractRecursive( path ,archives):
    i=0
    for dirpath, dirnames, filenames in os.walk( path ):
        for f in filenames:
            fp = os.path.join( dirpath, f )
            i+=1
            print i
            file_type = m.file( fp ).split( "," )[0]
            if file_type in archives:
                arcExtract(fp,file_type,path,True)
                extractRecursive(path,archives) # 递归调用自身
    return "Done"

def arcExtract(file_path,file_type,extracted_path="/home/v3ss/Downloads/extracted",unlink=False):
    import subprocess,shlex

    if file_type in pst_types:
        cmd = "readpst -o  '%s' -S '%s'" % (extracted_path,file_path)
    else:
        cmd = "7z -y -r -o%s x '%s'" % (extracted_path,file_path)

    print cmd
    args= shlex.split(cmd)
    print args

    try:
        sp = subprocess.Popen( args, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE )
        out, err = sp.communicate()
        print out, err
        ret = sp.returncode
    except OSError:
        print "Error no %s  Message %s" % (OSError.errno,OSError.message)
        pass

    if ret == 0:
        if unlink==True:
            os.unlink(file_path)
        return "OK!"
    else:
        return "Failed"

if __name__ == '__main__':
    extractRecursive( 'Path/To/Archives' ,archive_type)

解决方案

为了避免递归提取过多,我们只需要修改 extractRecursive 函数,不再在解压完成后再次调用自身。

def extractRecursive( path ,archives, extracted_archives=None):
    i = 0
    if not extracted_archives:
        extracted_archives = set()

    for dirpath, dirnames, filenames in os.walk( path ):
        for f in filenames:
            fp = os.path.join( dirpath, f )
            i+=1
            print i
            file_type = m.file( fp ).split( "," )[0]
            if file_type in archives and fp not in extracted_archives:
                extracted_archives.add(fp)
                extracted_in.add(dirpath)
                arcExtract(fp, file_type, path, True)

    for path in extracted_in:
        # 不再递归调用自身
        # extractRecursive(path, archives, extracted_archives)

    return "Done"

现在,extractRecursive 函数不再在解压完成后再次调用自身,而是继续遍历下一个目录。这样就可以避免递归提取过多,提高性能。

使用os.walk提取压缩文件并避免递归提取并不难,只要你熟悉Python的文件操作和zipfile模块的基本用法。os.walk提供了一种逐级遍历目录结构的简单方法,而zipfile模块则可以用来处理压缩文件。

主要的挑战可能在于理解如何在遍历文件时过滤出压缩文件,并且在解压缩时避免递归提取。但一旦理解了这个概念,编写相应的代码并不复杂。

我已经给出了一个示例代码,演示了如何使用os.walkzipfile模块来实现这一功能。你可以参考该示例并根据需要进行调整。如果有任何困难或疑问,随时向我提问,我会尽力帮助你解决问题。

你可能感兴趣的:(ui,xhtml,javascript,开发语言,android,服务器,爬虫)