您的日常生活中多久使用一次zip文件?
如果您曾经使用zip文件,那么您会知道许多文件和目录都被压缩到一个具有 .zip 文件扩展的文件中。
因此,要读取该文件,我们需要从zip格式中提取它们。
在本教程中,我们将实施一些Pythonic方法,用于在ZIP文件上执行各种操作,而无需提取它们。
为此,我们将使用Python的zipfile
模块来很好,轻松地处理该过程。
什么是zip文件?
如上所述,zip文件包含一个或多个已被压缩的文件或目录。
zip是支持 无损数据压缩的存档文件格式。
无损压缩意味着原始数据将从压缩数据中完美地重构而不会丢失任何信息。
如果您想知道什么是存档文件,那么它是由一个或多个文件及其元数据组成的计算机文件。
。这种格式最初是在1989年创建的,最初是在PKware,Inc。的PKZIP实用程序中实施的,作为Thom Henderson先前的ARC压缩格式的替代。然后,除了pkzip.Source
以外,ZIP格式得到了许多软件实用程序的支持
插图显示如何将文件放在磁盘上。Source
zip文件的需求是什么?
zip文件对于那些使用计算机并处理大型数字信息的人至关重要,因为它允许他们
-
通过压缩文件的大小而不会丢失任何信息。
来减少存储要求
-
提高网络的传输速度。
-
将您的所有相关文件累积到一个档案中,以进行更好的管理。
-
通过加密文件来提供安全性。
如何使用Python操纵ZIP文件?
python提供了多种操纵邮政编码的工具,包括一些低级Python库,例如lzma,bz2,zlib,zlib,tarfile,以及许多其他帮助使用特定压缩算法来压缩和解压缩文件的其他帮助。
。除了这些python具有一个名为zipfile
的高级模块,该模块可帮助我们读取,写作,创建,提取和列出zip文件的内容。
Python的Zipfile
zipfile
模块确实提供了方便的类和功能,用于阅读,写作和提取zip文件。
,但确实有限制:
-
数据解密过程很慢,因为它在纯python上运行。
-
它无法处理加密zip文件的创建。
-
当前不支持使用多磁带zip文件。
打开ZIP文件用于阅读和写作
zipfile
具有一个类ZipFile
,它允许我们以不同的模式打开zip文件,并且完全像Python的open()函数一起工作。
有四种类型的模式 -
-
r
:在阅读模式下打开文件。默认 -
w
:写作模式。 -
a
:附加到现有文件。 -
x
:创建和写一个新文件。
zipfile也是上下文管理器,因此支持
with
语句。Source
import zipfile
with zipfile.ZipFile("sample.zip", mode="r") as arch:
arch.printdir()
.........
File Name Modified Size
document.txt 2022-07-04 18:13:36 52
data.txt 2022-07-04 18:17:30 37538
hello.md 2022-07-04 18:33:02 7064
在这里,我们可以看到已经列出了sample.zip
文件夹中的所有文件。
在ZipFile
中,第一个参数我们提供的是文件的路径,是字符串。
然后,我们提供的第二个参数是模式。读取模式默认是您是否通过它无关紧要。
然后,我们在 文件名 修改 大小 我们将使用 第一个代码块成功运行并打印了 我们可以通过使用 如果文件是有效的zip文件,则返回 打开邮政编码以供写作,使用写模式 如果您要编写的文件存在,则 添加多个文件 注意:您要提供的文件作为参数 如果您尝试创建目录或传递不存在的文件,它将抛出 将文件附加到现有的zip档案中使用模式 有一些方法可以帮助我们阅读邮政编码的元数据。 还有一个我们已经使用的 使用 让我们看看更多方法 0 - 对于Windows 3 - 对于unix 显示使用 成员文件称为zip档案中存在的文件。 要在不提取成员文件的内容的情况下读取内容的内容,然后我们使用 我们使用saparator 除了 我们可以将 有两种提取Zip Archive 所有成员文件将在您当前的工作目录中提取到名为 创建zip文件只是编写现有文件。 ,或者您可以直接指定全名来添加文件。 我们可以使用 Shutil模块有助于在Python中执行高级文件操作。 这里的 使用 这里的 通常,当我们使用 就像成员文件存储在存档的容器中一样。 所以,我们需要在 有3种压缩文件的常数: 我们还可以添加压缩级别。我们可以在 您是否知道 这里有一些选项,使我们可以从命令行列出,创建和提取邮政编码。 它的作用就像 它将创建一个名为 创建一个zip文件来存档整个目录 phe,这是一个长长的模块,本文仍然没有覆盖所有内容。 但是,可以从 zip文件确实具有一些好处
我们当然学到了一些有用的操作,我们可以使用 阅读,编写和提取现有的邮政编码 阅读元数据 创建邮政编码 操纵成员文件 从命令行运行 python发电机以及它们的工作方式有什么特别之处? How to convert bytes into a string in Python? Understanding the different uses of asterisk(*) in Python。 Different ways to display web and local images in Jupyter Notebook? How to access list items within the dictionary in Python? What is the difference between sort() and sorted() in Python? How to use super() function in Python classes? What are context managers in Python? 这就是目前的全部 保持编码 arch
上调用了.printdir()
,它以ZipFile
的实例为 以用户友好的格式打印目录
通过使用尝试&除了处理错误
BadZipFile
类如何处理zipfile
,该类别提供了易于阅读的错误。
# Provided valid zip file
try:
with zipfile.ZipFile("sample.zip") as arch:
arch.printdir()
except zipfile.BadZipFile as error:
print(error)
.........
File Name Modified Size
document.txt 2022-07-04 18:13:36 52
data.txt 2022-07-04 18:17:30 37538
hello.md 2022-07-04 18:33:02 7064
# Provided bad zip file
try:
with zipfile.ZipFile("not_valid_zip.zip") as arch:
arch.printdir()
except zipfile.BadZipFile as error:
print(error)
.........
File is not a zip file
sample.zip
文件的内容,因为我们提供的zip文件是有效的zip文件,而我们提供了不良的zip文件 <<<。 /p>
is_zipfile
函数检查zip文件是否有效。
# Example 1
valid = zipfile.is_zipfile("bad_sample.zip")
print(valid)
.........
False
# Example 2
valid = zipfile.is_zipfile("sample.zip")
print(valid)
........
True
True
,否则返回False
。
# Print content if a file is valid
if zipfile.is_zipfile("sample.zip"):
with zipfile.ZipFile("sample.zip") as arch:
arch.printdir()
else:
print("This is not a valid ZIP format.")
.........
File Name Modified Size
document.txt 2022-07-04 18:13:36 52
data.txt 2022-07-04 18:17:30 37538
hello.md 2022-07-04 18:33:02 7064
if zipfile.is_zipfile("bad_sample.zip"):
with zipfile.ZipFile("sample.zip") as arch:
arch.printdir()
else:
print("This is not a valid ZIP format file.")
.........
This is not a valid ZIP format file.
编写zip文件
w
。w
将截断现有文件并写入您传递的新内容。
import zipfile
# Adding a file
with zipfile.ZipFile('geekpython.zip', 'w') as myzip:
myzip.write('geek.txt')
myzip.printdir()
........
File Name Modified Size
geek.txt 2022-07-05 14:52:01 85
geek.txt
将添加到运行代码后创建的geekpython.zip
。
import zipfile
# Adding multiple files
with zipfile.ZipFile('geekpython.zip', 'w') as myzip:
myzip.write('geek.txt')
myzip.write('program.py')
myzip.printdir()
........
File Name Modified Size
geek.txt 2022-07-05 14:52:01 85
program.py 2022-07-05 14:52:01 136
.write
应该存在。FileNotFoundError
。
import zipfile
# Passing a non-existing directory
with zipfile.ZipFile('hello/geekpython.zip', 'w') as myzip:
myzip.write('geek.txt')
.........
FileNotFoundError: [Errno 2] No such file or directory: 'hello/geekpython.zip'
import zipfile
# Passing a non-existing file
with zipfile.ZipFile('geekpython.zip', 'w') as myzip:
myzip.write('hello.txt')
........
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'hello.txt'
将文件附加到现有的zip存档
a
。
import zipfile
# Appending files to the existing zip file
with zipfile.ZipFile('geekpython.zip', 'a') as myzip:
myzip.write("index.html")
myzip.write("program.py")
myzip.printdir()
.........
File Name Modified Size
geek.txt 2022-07-05 14:52:00 85
index.html 2022-07-05 15:32:35 176
program.py 2022-07-05 14:52:01 136
阅读元数据
.getinfo(filename)
:它返回一个ZipInfo对象,该对象包含有关filename
提供的成员文件的信息。.infolist()
:返回一个包含档案中每个成员的zipinfo对象的列表。.namelist()
:按名称返回存档成员列表。.printdir()
的函数。
import zipfile
with zipfile.ZipFile("geekpython.zip", mode="r") as arch:
myzip = arch.getinfo("geek.txt")
print(myzip.filename)
>>> geek.txt
print(myzip.date_time)
>>> (2022, 7, 5, 14, 52, 0)
print(myzip.file_size)
>>> 85
print(myzip.compress_size)
>>> 85
.infolist()
在指定的档案中提取有关文件的信息
import zipfile
import datetime
date = datetime.datetime
with zipfile.ZipFile("geekpython.zip", "r") as info:
for arch in info.infolist():
print(f"The file name is: {arch.filename}")
print(f"The file size is: {arch.file_size} bytes")
print(f"The compressed size is: {arch.compress_size} bytes")
print(f"Date of creation: {date(*arch.date_time)}")
print("-" * 15)
.........
The file name is: geek.txt
The file size is: 85 bytes
The compressed size is: 85 bytes
Date of creation: 2022-07-05 14:52:00
---------------
The file name is: index.html
The file size is: 176 bytes
The compressed size is: 176 bytes
Date of creation: 2022-07-05 15:32:34
---------------
The file name is: program.py
The file size is: 136 bytes
The compressed size is: 136 bytes
Date of creation: 2022-07-05 14:52:00
---------------
import zipfile
with zipfile.ZipFile("sample.zip", "r") as info:
for arch in info.infolist():
if arch.create_system == 0:
system = "Windows"
elif arch.create_system == 3:
system = "UNIX"
else:
system = "Unknown"
print(f"ZIP version: {arch.create_version}")
print(f"Create System: {system}")
print(f"External Attributes: {arch.external_attr}")
print(f"Internal Attributes: {arch.internal_attr}")
print(f"Comments: {arch.comment}")
print("-" * 15)
.........
ZIP version: 20
Create System: Windows
External Attributes: 32
Internal Attributes: 1
Comments: b''
---------------
ZIP version: 20
Create System: Windows
External Attributes: 32
Internal Attributes: 1
Comments: b''
---------------
ZIP version: 20
Create System: Windows
External Attributes: 32
Internal Attributes: 1
Comments: b''
---------------
.create_system
返回了整数
.namelist()
的示例
import zipfile
with zipfile.ZipFile("geekpython.zip", "r") as files:
for files_list in files.namelist():
print(files_list)
.........
geek.txt
index.html
program.py
阅读和写作成员文件
.read()
。它占据了存档中文件的名称,而pwd
是用于加密文件的密码。
import zipfile
with zipfile.ZipFile("geekpython.zip", "r") as zif:
for lines in zif.read("intro.txt").split(b"\r\n"):
print(lines)
.........
b'Hey, Welcome to GeekPython!'
b''
b'Are you enjoying it?'
b''
b"Now it's time, see you later!"
b''
/r/n
添加了.split()
将字节流打印到行中,并添加了b
作为后缀,因为我们正在使用字节对象。.read()
外,我们可以使用.open()
,它允许我们以灵活的方式读取,写入和添加一个新文件,因为就像open()
函数一样,它实现了上下文管理器协议,因此支持with
语句。
import zipfile
with zipfile.ZipFile("sample.zip", "r") as my_zip:
with my_zip.open("document.txt", "r") as data:
for text in data:
print(text)
.........
b'Hey, I a document file inside the sample.zip folder.\r\n'
b'\r\n'
b'Are you enjoying it.'
.open()
与Write Mode w
一起创建一个新的成员文件并向其写入内容,然后我们可以将其附加到现有的存档。
import zipfile
with zipfile.ZipFile("sample.zip", "a") as my_zip:
with my_zip.open("file.txt", "w") as data_file:
data_file.write(b"Hi, I am a new file.")
with zipfile.ZipFile("sample.zip", mode="r") as archive:
archive.printdir()
print("-" * 20)
for line in archive.read("file.txt").split(b"\n"):
print(line)
.........
File Name Modified Size
data.txt 2022-07-04 18:17:30 37538
hello.md 2022-07-04 18:33:02 7064
document.txt 2022-07-06 17:08:36 76
file.txt 1980-01-01 00:00:00 20
--------------------
b'Hi, I am a new file.'
提取拉链档案
.extractall()
-这使我们能够在当前工作目录中提取所有存档的所有成员。我们还可以指定我们选择的目录的路径。
import zipfile
with zipfile.ZipFile("geekpython.zip", "r") as file:
file.extractall("files")
files
的文件夹中。您可以指定另一个目录。
.extract()
-允许我们从存档到当前工作目录中提取成员。您必须牢记一件事,需要指定会员的全名,否则必须是ZipInfo
对象。
import zipfile
with zipfile.ZipFile("geekpython.zip", "r") as file:
file.extract("hello.txt")
hello.txt
将从档案中提取到当前工作目录。您可以指定您选择的输出目录。您只需要将path="output_directory/"
指定为extract()
中的参数。
创建zip文件
# Creating archive using zipfile module
files = ["hello.txt", "geek.md", "python.txt"]
with zipfile.ZipFile("archive_created.zip", "w") as archive:
for file in files:
archive.write(file)
import zipfile
with zipfile.ZipFile("another_archive.zip", "w") as archive:
archive.write("hello.txt")
archive.write("geek.md")
archive.write("python.txt")
使用 shutil 创建zip文件
shutil
制作邮政编码,并提供了一种简单的方法。
import shutil
shutil.make_archive("archive", "zip", "files")
archive
是文件名将是作为邮政编码创建的,zip
是扩展名,将添加到文件中名称,而files
是一个文件夹,其数据将被存档。shutil
解开zip档案
import shutil
shutil.unpack_archive("archive.zip", "archive")
archive.zip
是 zip存档,archive
是提取后要给出的文件的名称。
压缩zip文件
zipfile
制作邮政编码时,我们得到的结果实际上是未压缩,因为默认情况下它使用ZIP_STORED压缩方法。ZipFile
中传递一个参数compression
。
zipfile.ZIP_DEFLATED
-需要一个zlib
模块,压缩方法是 deflate 。zipfile.ZIP_BZIP2
-需要一个bz2
模块,压缩方法为 bzip2 。zipfile.ZIP_LZMA
-需要一个lzma
模块,压缩方法为 lzma 。
import zipfile
with zipfile.ZipFile("compressed.zip", "w", compression=zipfile.ZIP_DEFLATED) as archive:
archive.write("geek.md")
archive.write("python.txt")
archive.write("hello.txt")
import zipfile
with zipfile.ZipFile("bzip_compressed.zip", "w", compression=zipfile.ZIP_BZIP2) as archive:
archive.write("geek.md")
archive.write("python.txt")
archive.write("hello.txt")
0
到9
之间给出一个值。
import zipfile
with zipfile.ZipFile("max_compressed.zip", "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive:
archive.write("geek.md")
archive.write("python.txt")
archive.write("hello.txt")
zipfile
可以从命令行?
从命令行接口运行Zipfile
-l
或--list
:列在zipfile中。
python -m zipfile -l data.zip
.........
File Name Modified Size
Streamlit-Apps-master/ 2022-06-30 23:31:36 0
Streamlit-Apps-master/Covid-19.csv 2022-06-30 23:31:36 1924
Streamlit-Apps-master/Covid-Banner.png 2022-06-30 23:31:36 538140
Streamlit-Apps-master/Procfile 2022-06-30 23:31:36 40
Streamlit-Apps-master/Readme.md 2022-06-30 23:31:36 901
Streamlit-Apps-master/WebAppPreview.png 2022-06-30 23:31:36 145818
Streamlit-Apps-master/app.py 2022-06-30 23:31:36 3162
Streamlit-Apps-master/requirements.txt 2022-06-30 23:31:36 46
Streamlit-Apps-master/setup.sh 2022-06-30 23:31:36 220
.printdir()
。
-c
或--create
:从源文件创建Zipfile。
python -m zipfile --create shell.zip python.txt hello.txt
shell.zip
的邮政编码,并添加上面指定的文件名。
python -m zipfile --create directory.zip source/
python -m zipfile -l directory.zip
.........
File Name Modified Size
source/ 2022-07-07 17:22:42 0
source/archive/ 2022-07-07 10:58:06 0
source/archive/hello.txt 2022-07-07 10:58:06 62
source/archive/index.html 2022-07-07 10:58:06 176
source/archive/intro.txt 2022-07-07 10:58:06 86
source/archive/program.py 2022-07-07 10:58:06 136
source/geek.md 2022-07-07 15:50:28 45
source/hello.txt 2022-07-07 12:21:22 61
-e
或--extract
:将zipfile提取到目标目录中。
python -m zipfile --extract directory.zip extracted/
directory.zip
将提取到extracted
目录中。
-t
或--test
:测试邮政编码是否有效。
python -m zipfile --test bad_sample.zip
.........
Traceback (most recent call last):
...
BadZipFile: File is not a zip file
结论
zipfile
模块开始并操纵邮政编码而无需提取它们是足够的。zipfile
模块在邮政编码上执行这些操作,例如:
zipfile
如果您喜欢这个