如果您使用计算机已有一段时间,则可能遇到了扩展名为.zip的文件。 它们是特殊文件,可以保存许多其他文件,文件夹和子文件夹的压缩内容。 这使它们对于通过Internet传输文件非常有用。 您是否知道可以使用Python压缩或提取文件?

本教程将教您如何在Python中使用zipfile模块,一次提取或压缩单个或多个文件。

压缩单个文件

这很容易,只需要很少的代码。 我们首先导入zipfile模块,然后通过将第二个参数指定为“ w”以写入模式打开ZipFile对象。 第一个参数是文件本身的路径。 这是您需要的代码:

import zipfile
    	
jungle_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\jungle.zip', 'w')
jungle_zip.write('C:\\Stories\\Fantasy\\jungle.pdf', compress_type=zipfile.ZIP_DEFLATED)

jungle_zip.close()

请注意,我将以Windows样式格式在所有代码段中指定路径; 如果您使用的是Linux或Mac,则需要进行适当的更改。

您可以指定不同的压缩方法来压缩文件。 Python 3.3版中添加了更新的方法BZIP2LZMA ,并且还有一些其他工具也不支持这两种压缩方法。 因此,仅使用DEFLATED方法是安全的。 您仍然应该尝试这些方法,以查看压缩文件大小的差异。

压缩多个文件

这有点复杂,因为您需要遍历所有文件。 以下代码应压缩给定文件夹中所有扩展名为pdf的文件:

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()

这次,我们导入了os模块,并使用其walk()方法遍历了原始文件夹内的所有文件和子文件夹。 我只压缩目录中的pdf文件。 您还可以使用if语句为每种格式创建不同的存档文件。

如果不想保留目录结构,则可以使用以下行将所有文件放在一起:

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)

write()方法接受三个参数。 第一个参数是我们要压缩的文件的名称。 第二个参数是可选的,允许您为压缩文件指定其他文件名。 如果未指定任何内容,则使用原始名称。

提取所有文件

您可以使用extractall()方法将所有文件和文件夹从zip文件中提取到当前工作目录中。 您还可以将文件夹名称传递给extractall()以提取特定目录中的所有文件和文件夹。 如果您传递的文件夹不存在,则此方法将为您创建一个。 这是可用于提取文件的代码:

import zipfile
    	
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip')
fantasy_zip.extractall('C:\\Library\\Stories\\Fantasy')

fantasy_zip.close()

如果要提取多个文件,则必须提供要提取的文件名作为列表。

提取单个文件

这类似于提取多个文件。 一个区别是这次您需要首先提供文件名,然后再提供将其解压缩的路径。 另外,您需要使用extract()方法而不是extractall() 。 这是提取单个文件的基本代码段。

import zipfile
    	
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip')
fantasy_zip.extract('Fantasy Jungle.pdf', 'C:\\Stories\\Fantasy')

fantasy_zip.close()

读取Zip文件

考虑一种情况,您需要查看zip存档是否包含特定文件。 到目前为止,您唯一的选择是提取存档中的所有文件。 同样,您可能只需要提取大于特定大小的那些文件。 zipfile模块允许我们查询档案的内容,而无需提取档案。

使用ZipFile对象的namelist()方法将按名称返回档案的所有成员的列表。 要获取有关存档中特定文件的信息,可以使用ZipFile对象的getinfo()方法。 这将使您能够访问特定于该文件的信息,例如文件的压缩和未压缩大小或其最后修改时间。 我们待会儿再讲。

当有很多文件需要处理时,在所有文件上一个一个地调用getinfo()方法可能是一个很麻烦的过程。 在这种情况下,您可以使用infolist()方法返回一个列表,该列表包含存档中每个成员的ZipInfo对象。 这些对象在列表中的顺序与实际zipfile的顺序相同。

您还可以使用read(file)方法直接从存档中read(file)特定文件的内容,其中file是您要读取的文件的名称。 为此,必须以读取或追加模式打开存档。

要从存档中获取单个文件的压缩大小,可以使用compress_size属性。 同样,要知道未压缩的大小,可以使用file_size属性。

下面的代码使用我们刚刚讨论的属性和方法仅提取那些大小小于1MB的文件。

import zipfile

stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip')

for file in stories_zip.namelist():
    if stories_zip.getinfo(file).file_size < 1024*1024:
		stories_zip.extract(file, 'C:\\Stories\\Short\\Funny')
        
stories_zip.close()

要了解上次修改存档中特定文件的时间和日期,可以使用date_time属性。 这将返回六个值的元组。 值将按该特定顺序为年,月,日,小时,分钟和秒。 年份将始终大于或等于1980,并且小时,分钟和秒从零开始。

import zipfile

stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip')

thirsty_crow_info = stories_zip.getinfo('The Thirsty Crow.pdf')

print(thirsty_crow_info.date_time)
print(thirsty_crow_infopress_size)
print(thirsty_crow_info.file_size)
        
stories_zip.close()

有关原始文件大小和压缩文件大小的信息可以帮助您确定是否值得压缩文件。 我相信它也可以在其他情况下使用。

最后的想法

从本教程可以明显看出,使用zipfile模块压缩文件为您提供了很大的灵活性。 您可以根据目录的类型,名称或大小将目录中的不同文件压缩到不同的档案中。 您还可以决定是否要保留目录结构。 同样,在提取文件时,您可以根据自己的标准(例如大小等)将它们提取到所需的位置。

老实说,通过编写自己的代码来压缩和提取文件对我来说也非常令人兴奋。 希望您喜欢本教程,如果有任何疑问,请在评论中告诉我。

学习Python

无论您是刚刚起步还是想学习新技能的经验丰富的程序员,都可以通过我们完整的python教程指南学习Python。

翻译自: https://code.tutsplus/tutorials/compressing-and-extracting-files-in-python--cms-26816

更多推荐

用Python压缩和提取文件