python【模块】zipfile压缩文件管理(1)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: python【模块】zipfile压缩文件管理(1)

python 模块 zipfile压缩文件管理

文章目录

python 模块 zipfile压缩文件管理

1. 简介

2. 什么是 ZIP 文件?

3. 为什么使用 ZIP 文件?

4. Python 可以操作 ZIP 文件吗?

5. 使用 Python 操作现有的 ZIP 文件zipfile

5.1 打开 ZIP 文件进行读写

5.2 从 ZIP 文件中读取元数据

5.3 读取和写入成员文件

5.4 将成员文件的内容作为文本读取

5.5 从您的 ZIP 档案中提取成员文件

5.6 使用后关闭 ZIP 文件

6. 创建、填充和提取您自己的 ZIP 文件

6.1 从多个常规文件创建 ZIP 文件

6.2 从目录构建 ZIP 文件

6.3 压缩文件和目录

6.4 按顺序创建 ZIP 文件

6.5 提取文件和目录

7. 探索其他类zipfile

7.1 Path在 ZIP 文件中查找

7.2 构建可导入的 ZIP 文件PyZipFile

7.3 zipfile从命令行运行

8. 使用其他库管理 ZIP 文件

9. 结论

1. 简介

Python zipfile是一个用于操作ZIP 文件的标准库模块。在归档和压缩数字数据时,这种文件格式是一种广泛采用的行业标准。您可以使用它将几个相关文件打包在一起。它还允许您减小文件大小并节省磁盘空间。最重要的是,它促进了计算机网络上的数据交换。


zipfile作为 Python 开发人员或 DevOps 工程师,了解如何使用该模块创建、读取、写入、填充、提取和列出 ZIP 文件是一项有用的技能。


在本教程中,您将学习如何:


使用 Python 从 ZIP 文件中读取、写入和提取文件zipfile

读取有关 ZIP 文件内容的元数据,使用zipfile

用于操作现有 ZIP 文件中的zipfile成员文件

创建新的 ZIP 文件以存档和压缩文件

如果您经常处理 ZIP 文件,那么这些知识可以帮助您简化工作流程,从而自信地处理文件。


要充分利用本教程,您应该了解使用文件、使用with语句、使用 处理文件系统路径pathlib以及使用类和面向对象编程的基础知识。

2. 什么是 ZIP 文件?

ZIP 文件是当今数字世界中广为人知的流行工具。这些文件相当流行并广泛用于计算机网络(尤其是 Internet)上的跨平台数据交换。


您可以使用 ZIP 文件将常规文件捆绑到一个存档中,压缩数据以节省一些磁盘空间,分发您的数字产品等等。在本教程中,您将学习如何使用 Python 的zipfile模块操作 ZIP 文件。


您可能已经遇到并使用过 ZIP 文件。是的,.zip文件扩展名无处不在!ZIP 文件,也称为ZIP 档案,是使用ZIP 文件格式的文件。


PKWARE是创建并首先实施此文件格式的公司。该公司整理并维护当前的格式规范,该规范是公开的,允许创建使用 ZIP 文件格式读写文件的产品、程序和流程。


ZIP 文件格式是一种跨平台、可互操作的文件存储和传输格式。它结合了无损数据压缩、文件管理和数据加密。


数据压缩不是将存档视为 ZIP 文件的必要条件。因此,您可以在 ZIP 存档中包含压缩或未压缩的成员文件。ZIP 文件格式支持多种压缩算法,但Deflate是最常见的。该格式还支持使用CRC32进行信息完整性检查。


尽管还有其他类似的存档格式,例如RAR和TAR文件,但 ZIP 文件格式已迅速成为高效数据存储和计算机网络上数据交换的通用标准。


ZIP 文件无处不在。例如,Microsoft Office和Libre Office等办公套件依赖 ZIP 文件格式作为其文档容器文件。这意味着 , .docx, .xlsx, .pptx, .odt,.ods文件.odp实际上是 ZIP 档案,其中包含构成每个文档的多个文件和文件夹。其他使用 ZIP 格式的常见文件包括.jar、.war和.epub文件。


您可能熟悉GitHub ,它为使用Git的软件开发和版本控制提供 Web 托管。当您将软件项目下载到本地计算机时,GitHub 使用 ZIP 文件打包软件项目。例如,您可以在 ZIP 文件中下载Python Basics: A Practical Introduction to Python 3书籍的练习解决方案,或者您可以下载您选择的任何其他项目。


ZIP 文件允许您将文件聚合、压缩和加密到单个可互操作且可移植的容器中。您可以流式传输 ZIP 文件、将它们分割成段、使它们自解压等等。

3. 为什么使用 ZIP 文件?

了解如何创建、读取、写入和提取 ZIP 文件对于使用计算机和数字信息的开发人员和专业人员来说可能是一项有用的技能。除其他好处外,ZIP 文件还允许您:


在不丢失信息的情况下减小文件大小及其存储要求

由于减小了大小和单文件传输,提高了网络传输速度

将多个相关文件打包到一个存档中,以实现高效管理

将您的代码捆绑到一个存档中以进行分发

使用加密来保护您的数据,这是当今的普遍要求

保证您信息的完整性,避免对您的数据进行意外和恶意更改

如果您正在寻找一种灵活、可移植且可靠的方式来归档您的数字文件,这些功能使 ZIP 文件成为 Python 工具箱的有用补充。

4. Python 可以操作 ZIP 文件吗?

是的!Python 有几个工具可以让你操作 ZIP 文件。其中一些工具在 Python标准库中可用。它们包括zlib用于使用特定压缩算法(例如、bz2、lzma等)压缩和解压缩数据的低级库。


Python 还提供了一个高级模块,称为zipfile专门用于创建、读取、写入、提取和列出 ZIP 文件的内容。在本教程中,您将了解 Pythonzipfile以及如何有效地使用它。

5. 使用 Python 操作现有的 ZIP 文件zipfile

Pythonzipfile提供了方便的类和函数,允许您创建、读取、写入、提取和列出 ZIP 文件的内容。以下是一些zipfile支持的附加功能:


大于 4 GiB 的 ZIP 文件(ZIP64 文件)

数据解密

多种压缩算法,例如 Deflate、Bzip2和LZMA

使用 CRC32 进行信息完整性检查

请注意,它zipfile确实有一些限制。例如,当前的数据解密功能可能非常慢,因为它使用纯 Python 代码。该模块无法处理加密 ZIP 文件的创建。最后,也不支持使用多磁盘 ZIP 文件。尽管有这些限制,zipfile它仍然是一个伟大而有用的工具。继续阅读以探索其功能。

5.1 打开 ZIP 文件进行读写

在zipfile模块中,您会找到ZipFile该类。这个类的工作方式很像 Python 的内置open()函数,允许您使用不同的模式打开 ZIP 文件。读取模式 ( “r”) 是默认值。您还可以使用写入 ( “w”)、附加 ( “a”) 和独占 ( “x”) 模式。稍后您将了解更多有关这些内容的信息。


ZipFile实现上下文管理器协议,以便您可以在with语句中使用该类。此功能允许您快速打开和使用 ZIP 文件,而无需担心在完成工作后关闭文件。


在编写任何代码之前,请确保您拥有将要使用的文件和存档的副本:

为了准备好您的工作环境,请将下载的资源放入python-zipfile/主文件夹中的一个目录中。将文件放在正确的位置后,移动到新创建的目录并在那里启动 Python 交互式会话。


要热身,首先要阅读名为 .zip 的 ZIP 文件sample.zip。为此,您可以ZipFile在阅读模式下使用:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     archive.printdir()
...
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
lorem.md                                  2021-09-07 19:50:10         2609
realpython.md                             2021-09-07 19:50:10          428

初始化程序的第一个参数ZipFile可以是一个字符串,表示您需要打开的 ZIP 文件的路径。这个参数也可以接受类似文件和类似路径的对象。在此示例中,您使用基于字符串的路径。


第二个参数ZipFile是一个单字母字符串,表示您将用于打开文件的模式。正如您在本节开头所了解的,ZipFile可以接受四种可能的模式,具体取决于您的需要。mode 位置参数默认为,因此"r"如果您想以只读方式打开存档,则可以去掉它。


在声明中with,您调用.printdir(). archive该archive 变量现在保存其自身的实例ZipFile。此功能提供了一种在屏幕上显示底层 ZIP 文件内容的快捷方式。该函数的输出具有用户友好的表格格式,包含三个信息列:


File Name

Modified

Size

如果你想在尝试打开它之前确保你的目标是一个有效的 ZIP 文件,那么你可以ZipFile在一个try…except语句中包装并捕获任何BadZipFile异常:

>>> import zipfile
>>> try:
...     with zipfile.ZipFile("sample.zip") as archive:
...         archive.printdir()
... except zipfile.BadZipFile as error:
...     print(error)
...
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
lorem.md                                  2021-09-07 19:50:10         2609
realpython.md                             2021-09-07 19:50:10          428
>>> try:
...     with zipfile.ZipFile("bad_sample.zip") as archive:
...         archive.printdir()
... except zipfile.BadZipFile as error:
...     print(error)
...
File is not a zip file

第一个示例成功打开sample.zip而没有引发BadZipFile异常。那是因为sample.zip具有有效的 ZIP 格式。另一方面,第二个示例没有成功打开bad_sample.zip,因为该文件不是有效的 ZIP 文件。


要检查有效的 ZIP 文件,您还可以使用以下is_zipfile()功能:

>>> import zipfile
>>> if zipfile.is_zipfile("sample.zip"):
...     with zipfile.ZipFile("sample.zip", "r") as archive:
...         archive.printdir()
... else:
...     print("File is not a zip file")
...
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
lorem.md                                  2021-09-07 19:50:10         2609
realpython.md                             2021-09-07 19:50:10          428
>>> if zipfile.is_zipfile("bad_sample.zip"):
...     with zipfile.ZipFile("bad_sample.zip", "r") as archive:
...         archive.printdir()
... else:
...     print("File is not a zip file")
...
File is not a zip file

在这些示例中,您使用条件语句withis_zipfile()作为条件。此函数接受一个filename参数,该参数保存文件系统中 ZIP 文件的路径。此参数可以接受字符串、类似文件或类似路径的对象。True如果filename是有效的 ZIP 文件,该函数将返回。否则,它返回False.


现在假设您要hello.txt使用. 为此,您可以使用写入模式 ( )。此模式打开一个 ZIP 文件进行写入。如果目标 ZIP 文件存在,则该模式会截断它并写入您传入的任何新内容。hello.zipZipFile"w"“w”


注意:如果您使用ZipFile现有文件,那么您应该小心使用该"w"模式。您可以截断 ZIP 文件并丢失所有原始内容。


如果目标 ZIP 文件不存在,则ZipFile在您关闭存档时为您创建它:

>>> import zipfile
>>> with zipfile.ZipFile("hello.zip", mode="w") as archive:
...     archive.write("hello.txt")
...
>>> with  zipfile.ZipFile("hello.zip", mode="r") as archive:
...      archive.printdir()
... 
File Name                                             Modified             Size
hello.txt                                      2022-02-18 15:27:40           83

运行此代码后,您的目录中将有一个hello.zip文件python-zipfile/。如果您使用 列出文件内容.printdir(),那么您会注意到它hello.txt会在那里。.write()在此示例中,您调用ZipFile对象。此方法允许您将成员文件写入 ZIP 存档。请注意,参数 to.write()应该是现有文件。


注意: ZipFile当您在写作模式下使用课程并且目标存档不存在时,它足够聪明,可以创建新存档。但是,如果这些目录尚不存在,则该类不会在目标ZIP 文件的路径中创建新目录。


这就解释了为什么以下代码不起作用:

>>> import zipfile
>>> with zipfile.ZipFile("missing/hello.zip", mode="w") as archive:
...     archive.write("hello.txt")
...
Traceback (most recent call last):
    ...
FileNotFoundError: [Errno 2] No such file or directory: 'missing/hello.zip'

因为missing/目标文件路径中的目录hello.zip不存在,所以会出现FileNotFoundError异常


附加模式 ( “a”) 允许您将新成员文件附加到现有 ZIP 文件。此模式不会截断存档,因此其原始内容是安全的。如果目标 ZIP 文件不存在,则该"a"模式会为您创建一个新文件,然后将您作为参数传递给.write().


要尝试该"a"模式,请继续将new_hello.txt文件添加到新创建的hello.zip存档中:

>>> import zipfile
>>> with zipfile.ZipFile("hello.zip", mode="a") as archive:
...     archive.write("new_hello.txt")
...
>>> with zipfile.ZipFile("hello.zip") as archive:
...     archive.printdir()
...
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
new_hello.txt                             2021-08-31 17:13:44           13

在这里,您使用附加模式添加new_hello.txt到hello.zip文件中。然后运行.printdir()以确认 ZIP 文件中存在新文件。


ZipFile还支持独占模式 ( “x”)。此模式允许您专门创建新的 ZIP 文件并将新的成员文件写入其中。当您想要制作一个新的 ZIP 文件而不覆盖现有文件时,您将使用独占模式。如果目标文件已经存在,那么你会得到FileExistsError.


"w"最后,如果您使用、“a"或模式创建 ZIP 文件"x”,然后在不添加任何成员文件的情况下关闭存档,则会ZipFile创建一个具有适当 ZIP 格式的空存档。

5.2 从 ZIP 文件中读取元数据

你已经付诸.printdir()行动了。这是一种有用的方法,可用于快速列出 ZIP 文件的内容。除了.printdir(),ZipFile该类还提供了几种从现有 ZIP 文件中提取元数据的便捷方法。

以下是这些方法的摘要:

1671077278688.png

使用这三个工具,您可以检索有关 ZIP 文件内容的大量有用信息。例如,看看下面的例子,它使用.getinfo()

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     info = archive.getinfo("hello.txt")
...
>>> info.file_size
83
>>> info.compress_size
83
>>> info.filename
'hello.txt'
>>> info.date_time
(2021, 9, 7, 19, 50, 10)

正如您在上表中了解到的,.getinfo()将成员文件作为参数并返回一个ZipInfo包含有关它的信息的对象。


注意:ZipInfo不打算直接实例化。.getinfo()and方法在您调用它们时会自动.infolist()返回对象。ZipInfo但是,ZipInfo它包含一个名为的类方法.from_file(),它允许您在需要时显式地实例化该类。


ZipInfo对象具有多个属性,可让您检索有关目标成员文件的有价值信息。例如,.file_size分别.compress_size保存原始文件和压缩文件的大小(以字节为单位)。该类还有一些其他有用的属性,例如.filenameand .date_time,它们返回文件名和最后修改日期。


注意:默认情况下,ZipFile不会压缩输入文件以将它们添加到最终存档中。这就是上例中大小和压缩大小相同的原因。您将在下面的压缩文件和目录部分了解有关此主题的更多信息。


使用.infolist(),您可以从给定存档中的所有文件中提取信息。这是一个使用此方法生成包含sample.zip存档中所有成员文件信息的最小报告的示例:

>>> import datetime
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     for info in archive.infolist():
...         print(f"Filename: {info.filename}")
...         print(f"Modified: {datetime.datetime(*info.date_time)}")
...         print(f"Normal size: {info.file_size} bytes")
...         print(f"Compressed size: {info.compress_size} bytes")
...         print("-" * 20)
...
Filename: hello.txt
Modified: 2021-09-07 19:50:10
Normal size: 83 bytes
Compressed size: 83 bytes
--------------------
Filename: lorem.md
Modified: 2021-09-07 19:50:10
Normal size: 2609 bytes
Compressed size: 2609 bytes
--------------------
Filename: realpython.md
Modified: 2021-09-07 19:50:10
Normal size: 428 bytes
Compressed size: 428 bytes
--------------------

该for循环遍历来自 的ZipInfo对象.infolist(),检索文件名、最后修改日期、正常大小和每个成员文件的压缩大小。在此示例中,您习惯于datetime以人类可读的方式格式化日期。


注意:上面的示例改编自zipfile — ZIP Archive Access。


如果您只需要对 ZIP 文件执行快速检查并列出其成员文件的名称,则可以使用.namelist():

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     for filename in archive.namelist():
...         print(filename)
...
hello.txt
lorem.md
realpython.md

由于此输出中的文件名是 的有效参数.getinfo(),因此您可以结合使用这两种方法来仅检索有关选定成员文件的信息。


例如,您可能有一个 ZIP 文件,其中包含不同类型的成员文件(.docx、.xlsx、.txt等)。无需使用 获取完整信息.infolist(),您只需获取有关.docx文件的信息。然后,您可以按扩展名过滤文件并仅调用.getinfo()您的.docx文件。来吧,试一试!

5.3 读取和写入成员文件

有时您有一个 ZIP 文件并且需要读取给定成员文件的内容而不解压缩它。为此,您可以使用.read(). 此方法采用成员文件name并将该文件的内容作为字节返回:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     for line in archive.read("hello.txt").split(b"\n"):
...         print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to Real Python!'
b''
b"Ready to try Python's zipfile module?"
b''

要使用.read(),您需要打开 ZIP 文件以进行读取或附加。请注意,.read()将目标文件的内容作为字节流返回。在此示例中,您使用换行符作为分隔符将.split()流拆分为行。因为是对字节对象进行操作,所以需要在用作参数的字符串中添加前导。“\n”.split()b


ZipFile.read()还接受名为 . 的第二个位置参数pwd。此参数允许您提供用于读取加密文件的密码。要尝试此功能,您可以依赖sample_pwd.zip与本教程材料一起下载的文件:

>>> import zipfile
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
...     for line in archive.read("hello.txt", pwd=b"secret").split(b"\n"):
...         print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to Real Python!'
b''
b"Ready to try Python's zipfile module?"
b''
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
...     for line in archive.read("hello.txt").split(b"\n"):
...         print(line)
...
Traceback (most recent call last):
    ...
RuntimeError: File 'hello.txt' is encrypted, password required for extraction

在第一个示例中,您提供了secret读取加密文件的密码。该pwd参数接受字节类型的值。如果您.read()在未提供所需密码的情况下使用加密文件,那么您会得到一个RuntimeError,正如您在第二个示例中所指出的那样。


注意: Pythonzipfile支持解密。但是,它不支持创建加密的 ZIP 文件。这就是为什么您需要使用外部文件归档器来加密文件的原因。


一些流行的文件归档器包括适用于 Windows的7z和WinRAR 、适用于 Linux 的Ark和GNOME Archive

Manager以及适用于 macOS 的Archiver。


对于大型加密 ZIP 文件,请记住,解密操作可能非常缓慢,因为它是在纯 Python 中实现的。在这种情况下,请考虑使用专门的程序来处理您的档案,而不是使用zipfile.


如果您经常使用加密文件,那么您可能希望避免在每次调用.read()或其他接受pwd参数的方法时提供解密密码。如果是这种情况,您可以使用ZipFile.setpassword()设置全局密码:

>>> import zipfile
>>> with zipfile.ZipFile("sample_pwd.zip", mode="r") as archive:
...     archive.setpassword(b"secret")
...     for file in archive.namelist():
...         print(file)
...         print("-" * 20)
...         for line in archive.read(file).split(b"\n"):
...             print(line)
...
hello.txt
--------------------
b'Hello, Pythonista!'
b''
b'Welcome to Real Python!'
b''
b"Ready to try Python's zipfile module?"
b''
lorem.md
--------------------
b'# Lorem Ipsum'
b''
b'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    ...

使用.setpassword(),您只需提供一次密码。ZipFile使用该唯一密码解密所有成员文件。

相反,如果您的 ZIP 文件对各个成员文件具有不同的密码,那么您需要使用以下pwd参数为每个文件提供特定密码.read()

>>> import zipfile
>>> with zipfile.ZipFile("sample_file_pwd.zip", mode="r") as archive:
...     for line in archive.read("hello.txt", pwd=b"secret1").split(b"\n"):
...         print(line)
...
b'Hello, Pythonista!'
b''
b'Welcome to Real Python!'
b''
b"Ready to try Python's zipfile module?"
b''
>>> with zipfile.ZipFile("sample_file_pwd.zip", mode="r") as archive:
...     for line in archive.read("lorem.md", pwd=b"secret2").split(b"\n"):
...         print(line)
...
b'# Lorem Ipsum'
b''
b'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    ...

在此示例中,您使用read和to readsecret1作为密码。要考虑的最后一个细节是,当您使用该参数时,您将覆盖您可能使用.hello.txtsecret2lorem.mdpwd.setpassword()


注意:调用.read()使用不受支持的压缩方法的 ZIP 文件会引发NotImplementedError. 如果所需的压缩模块在您的Python 安装中不可用,您也会收到错误消息。


如果您正在寻找一种更灵活的方式来读取成员文件并创建新成员文件并将其添加到存档中,那么ZipFile.open()它适合您。与内置open()函数一样,此方法实现了上下文管理器协议,因此它支持以下with语句:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     with archive.open("hello.txt", mode="r") as hello:
...         for line in hello:
...             print(line)
...
b'Hello, Pythonista!\n'
b'\n'
b'Welcome to Real Python!\n'
b'\n'
b"Ready to try Python's zipfile module?\n"

在本例中,您打开hello.txt阅读。的第一个参数.open()是name,表示要打开的成员文件。第二个参数是模式,默认"r"为正常模式。ZipFile.open()还接受pwd打开加密文件的参数。此参数的作用与 中的等效pwd参数相同.read()。


您也可以使用.open()与"w"模式。此模式允许您创建一个新的成员文件,向其中写入内容,最后将该文件附加到底层存档,您应该以附加模式打开它:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="a") as archive:
...     with archive.open("new_hello.txt", "w") as new_hello:
...         new_hello.write(b"Hello, World!")
...
13
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     archive.printdir()
...     print("------")
...     archive.read("new_hello.txt")
...
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
lorem.md                                  2021-09-07 19:50:10         2609
realpython.md                             2021-09-07 19:50:10          428
new_hello.txt                             1980-01-01 00:00:00           13
------
b'Hello, World!'

在第一个代码片段中,您sample.zip以附加模式 ( “a”) 打开。然后你new_hello.txt通过调用模式.open()来创建。"w"该函数返回一个支持的类文件对象.write(),它允许您将字节写入新创建的文件。


注意:您需要提供一个不存在的文件名到.open(),如果您使用基础存档中已经存在的文件名,那么您最终会得到一个重复的文件和一个UserWarning异常。


在此示例中,您b’Hello, World!'写入new_hello.txt. 当执行流程退出内部with语句时,Python 将输入字节写入成员文件。当外部with语句退出时,Python 将写入new_hello.txt底层 ZIP 文件sample.zip.


第二个代码片段确认它new_hello.txt现在是sample.zip. 在此示例的输出中要注意的一个细节是将新添加文件.write()的日期设置为,这是使用此方法时应牢记的奇怪行为。Modified1980-01-01 00:00:00

5.4 将成员文件的内容作为文本读取

正如您在上一节中所了解的,您可以使用.read()和.write()方法来读取和写入成员文件,而无需从包含的 ZIP 存档中提取它们。这两种方法都只适用于字节。


但是,当您有一个包含文本文件的 ZIP 存档时,您可能希望将其内容作为文本而不是字节来读取。至少有两种方法可以做到这一点。您可以使用:


bytes.decode()

io.TextIOWrapper

因为ZipFile.read()将目标成员文件的内容作为字节返回,.decode()所以可以直接对这些字节进行操作。该方法使用给定的字符编码格式将对象.decode()解码为字符串。bytes


以下是您可以用来从存档文件中.decode()读取文本的方法:hello.txtsample.zip

>>> import zipfile
>>>  with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     text = archive.read("hello.txt").decode(encoding="utf-8")
...
>>> print(text)
Hello, Pythonista!
Welcome to Real Python!
Ready to try Python's zipfile module?

在此示例中,您读取hello.txtas 字节的内容。然后调用.decode()将字节解码为使用UTF-8作为编码的字符串。要设置encoding参数,请使用"utf-8"字符串。但是,您可以使用任何其他有效编码,例如UTF-16或cp1252,它们可以表示为不区分大小写的字符串。请注意,这"utf-8"是 的encoding参数的默认值.decode()。


请务必记住,您需要事先知道要使用.decode(). 如果您使用了错误的字符编码,那么您的代码将无法将底层字节正确解码为文本,最终您可能会得到大量无法辨认的字符。


从成员文件中读取文本的第二个选项是使用io.TextIOWrapper提供缓冲文本流的对象。这个时候你需要使用.open()而不是.read(). 下面是一个将成员文件的内容作为文本流io.TextIOWrapper读取的示例:hello.txt

>>> import io
>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     with archive.open("hello.txt", mode="r") as hello:
...         for line in io.TextIOWrapper(hello, encoding="utf-8"):
...             print(line.strip())
...
Hello, Pythonista!
Welcome to Real Python!
Ready to try Python's zipfile module?

在此示例的内部with语句中,您从存档中打开hello.txt成员文件。sample.zip然后将生成的二进制文件类对象 ,hello作为参数传递给io.TextIOWrapper. hello这通过解码使用 UTF-8 字符编码格式的内容来创建缓冲文本流。因此,您可以直接从目标成员文件中获得文本流。


就像 with 一样.encode(),io.TextIOWrapper该类接受一个encoding参数。您应该始终为此参数指定一个值,因为默认文本编码取决于运行代码的系统,并且可能不是您尝试解码的文件的正确值。

5.5 从您的 ZIP 档案中提取成员文件

提取给定存档的内容是您将对 ZIP 文件执行的最常见操作之一。根据您的需要,您可能希望一次提取一个文件或一次提取所有文件。

ZipFile.extract()让你完成第一个任务。此方法采用member文件名并将其提取到由 . 表示的给定目录path。目标path默认为当前目录:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     archive.extract("new_hello.txt", path="output_dir/")
...
'output_dir/new_hello.txt'

现在new_hello.txt将在您的output_dir/目录中。如果目标文件名已经存在于输出目录中,则.extract()覆盖它而不要求确认。如果输出目录不存在,.extract()则为您创建它。请注意,.extract()返回提取文件的路径。


成员文件的名称必须是返回的文件全名.namelist()。它也可以是ZipInfo包含文件信息的对象。


您还可以使用.extract()加密文件。在这种情况下,您需要提供所需的pwd参数或使用 设置存档级密码.setpassword()。


在从档案中提取所有成员文件时,您可以使用.extractall(). 顾名思义,此方法将所有成员文件提取到目标路径,默认为当前目录:

>>> import zipfile
>>> with zipfile.ZipFile("sample.zip", mode="r") as archive:
...     archive.extractall("output_dir/")
...

运行此代码后,所有当前内容都sample.zip将在您的output_dir/目录中。如果您将不存在的目录传递给.extractall(),则此方法会自动创建该目录。最后,如果目标目录中已经存在任何成员文件,.extractall()则将覆盖它们而不要求您确认,因此请小心。


如果您只需要从给定存档中提取一些成员文件,那么您可以使用该members参数。此参数接受成员文件列表,该列表应该是手头存档中整个文件列表的子集。最后,就像 一样.extract(),该.extractall()方法也接受一个pwd参数来提取加密文件。

5.6 使用后关闭 ZIP 文件

有时,您可以方便地打开给定的 ZIP 文件而不使用with语句。在这些情况下,您需要在使用后手动关闭存档以完成任何写入操作并释放获取的资源。

为此,您可以调用.close()您的ZipFile对象:

>>> import zipfile
>>> archive = zipfile.ZipFile("sample.zip", mode="r")
>>> # Use archive in different parts of your code
>>> archive.printdir()
File Name                                        Modified             Size
hello.txt                                 2021-09-07 19:50:10           83
lorem.md                                  2021-09-07 19:50:10         2609
realpython.md                             2021-09-07 19:50:10          428
new_hello.txt                             1980-01-01 00:00:00           13
>>> # Close the archive when you're done
>>> archive.close()
>>> archive
<zipfile.ZipFile [closed]>

呼叫为您.close()关闭archive。您必须.close()在退出程序之前调用。否则,可能无法执行某些写入操作。例如,如果您打开一个 ZIP 文件以附加 ( “a”) 新成员文件,那么您需要关闭存档以写入文件。


相关文章
|
2天前
|
前端开发 Python
python之【Tkinter模块】
python之【Tkinter模块】
11 5
|
2天前
|
Python
|
3天前
|
关系型数据库 MySQL Python
pymysql模块,python与MySQL之间的交互
pymysql模块,python与MySQL之间的交互
|
3天前
|
Unix Linux 网络安全
python中连接linux好用的模块paramiko(附带案例)
该文章详细介绍了如何使用Python的Paramiko模块来连接Linux服务器,包括安装配置及通过密码或密钥进行身份验证的示例。
9 1
|
1天前
|
Python
7-14|salt之安装Python模块
7-14|salt之安装Python模块
|
3天前
|
数据可视化 搜索推荐 JavaScript
pyecharts模块的几个经典案例(python经典编程案例)
文章提供了多个使用pyecharts模块创建数据可视化的Python编程案例,展示如何生成各种类型的图表并进行定制化设置。
9 0
|
3天前
|
数据挖掘 Python
用python的tushare模块分析股票案例(python3经典编程案例)
该文章提供了使用Python的tushare模块分析股票数据的案例,展示了如何获取股票数据以及进行基本的数据分析。
11 0
|
1天前
|
存储 人工智能 数据挖掘
Python编程入门:从基础到实战
【9月更文挑战第26天】 在这篇文章中,我们将一起探索Python编程的奇妙世界。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的信息和技巧。我们将从Python的基本语法开始,然后逐步深入到更复杂的主题,如函数、类和模块。最后,我们将通过一个实际的项目来应用我们所学的知识。让我们一起开始这段Python编程之旅吧!
|
2天前
|
数据采集 人工智能 数据挖掘
Python编程入门:从基础到实战的快速指南
【9月更文挑战第25天】本文旨在为初学者提供一个简明扼要的Python编程入门指南。通过介绍Python的基本概念、语法规则以及实际案例分析,帮助读者迅速掌握Python编程的核心技能。文章将避免使用复杂的专业术语,而是采用通俗易懂的语言和直观的例子来阐述概念,确保内容的可读性和实用性。
|
1天前
|
Python
探索Python编程中的装饰器魔法
【9月更文挑战第26天】在Python的世界里,装饰器就像是一把瑞士军刀,小巧而功能强大。它们让代码更简洁、可维护性更强。本文将通过实际示例,带你领略装饰器的魔力,从基础到进阶,一步步揭开它的神秘面纱。
9 2