本文概述
目录
- 使用Zip文件的先决条件
- 什么是Zip文件?
- 用于Zip文件?
zipfile模块
例外情况
- zipfile.BadZipFile
- zipfile.LargeZipFile
类
- zipfile.ZipFile
- zipfile.ZipInfo
方法
- zipfile.is_zipfile()
处理Zip文件
- 提取一个Zip文件
- 使用密码提取一个邮编
- 创建Zip文件
- 写入Zip文件
- 将文件附加到压缩文件
问题
- 解决问题的步骤
- 尾注
使用Zip文件的先决条件
- 你必须了解Python的文件处理才能了解Zip文件处理。如果你不知道文件处理, 请转到W3Schools文件处理部分以学习。
- Python中的OOPS概念
- Python概念, 例如条件, 循环, 函数, 类等,
- 如果你不了解Python, 请参加srcmini的免费的Python数据科学入门课程, 以学习Python语言或阅读Python的官方文档。
打开此链接以下载我在接下来的部分中使用的所有Zip文件夹。
什么是Zip文件?
Zip是一种存档文件格式, 支持无损数据压缩。 Zip文件是包含一个或多个压缩文件的单个文件。
用于Zip文件?
- 压缩文件可帮助你将所有相关文件放在一个地方。
- 压缩文件有助于减小数据大小。
- 通过许多连接, Zip文件的传输速度比单个文件快。
使用dir()方法探索zipfile模块的所有方法和类。请参阅代码以获取zipfile模块的所有类和方法。
import zipfile # importing the 'zipfile' module
print(dir(zipfile))
['BZIP2_VERSION', 'BadZipFile', 'BadZipfile', 'DEFAULT_VERSION', 'LZMACompressor', 'LZMADecompressor', 'LZMA_VERSION', 'LargeZipFile', 'MAX_EXTRACT_VERSION', 'PyZipFile', 'ZIP64_LIMIT', 'ZIP64_VERSION', 'ZIP_BZIP2', 'ZIP_DEFLATED', 'ZIP_FILECOUNT_LIMIT', 'ZIP_LZMA', 'ZIP_MAX_COMMENT', 'ZIP_STORED', 'ZipExtFile', 'ZipFile', 'ZipInfo', '_CD64_CREATE_VERSION', '_CD64_DIRECTORY_RECSIZE', '_CD64_DIRECTORY_SIZE', '_CD64_DISK_NUMBER', '_CD64_DISK_NUMBER_START', '_CD64_EXTRACT_VERSION', '_CD64_NUMBER_ENTRIES_THIS_DISK', '_CD64_NUMBER_ENTRIES_TOTAL', '_CD64_OFFSET_START_CENTDIR', '_CD64_SIGNATURE', '_CD_COMMENT_LENGTH', '_CD_COMPRESSED_SIZE', '_CD_COMPRESS_TYPE', '_CD_CRC', '_CD_CREATE_SYSTEM', '_CD_CREATE_VERSION', '_CD_DATE', '_CD_DISK_NUMBER_START', '_CD_EXTERNAL_FILE_ATTRIBUTES', '_CD_EXTRACT_SYSTEM', '_CD_EXTRACT_VERSION', '_CD_EXTRA_FIELD_LENGTH', '_CD_FILENAME_LENGTH', '_CD_FLAG_BITS', '_CD_INTERNAL_FILE_ATTRIBUTES', '_CD_LOCAL_HEADER_OFFSET', '_CD_SIGNATURE', '_CD_TIME', '_CD_UNCOMPRESSED_SIZE', '_ECD_COMMENT', '_ECD_COMMENT_SIZE', '_ECD_DISK_NUMBER', '_ECD_DISK_START', '_ECD_ENTRIES_THIS_DISK', '_ECD_ENTRIES_TOTAL', '_ECD_LOCATION', '_ECD_OFFSET', '_ECD_SIGNATURE', '_ECD_SIZE', '_EndRecData', '_EndRecData64', '_FH_COMPRESSED_SIZE', '_FH_COMPRESSION_METHOD', '_FH_CRC', '_FH_EXTRACT_SYSTEM', '_FH_EXTRACT_VERSION', '_FH_EXTRA_FIELD_LENGTH', '_FH_FILENAME_LENGTH', '_FH_GENERAL_PURPOSE_FLAG_BITS', '_FH_LAST_MOD_DATE', '_FH_LAST_MOD_TIME', '_FH_SIGNATURE', '_FH_UNCOMPRESSED_SIZE', '_SharedFile', '_Tellable', '_ZipDecrypter', '_ZipWriteFile', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_compression', '_check_zipfile', '_get_compressor', '_get_decompressor', 'binascii', 'bz2', 'compressor_names', 'crc32', 'error', 'importlib', 'io', 'is_zipfile', 'lzma', 'main', 'os', 're', 'shutil', 'sizeCentralDir', 'sizeEndCentDir', 'sizeEndCentDir64', 'sizeEndCentDir64Locator', 'sizeFileHeader', 'stat', 'stringCentralDir', 'stringEndArchive', 'stringEndArchive64', 'stringEndArchive64Locator', 'stringFileHeader', 'struct', 'structCentralDir', 'structEndArchive', 'structEndArchive64', 'structEndArchive64Locator', 'structFileHeader', 'sys', 'threading', 'time', 'zlib']
你已经看到了许多正确的类和方法。但是, 你不会学习所有这些。你将仅学习一些使用Zip文件的类和方法。
让我们看一下一些有用的异常, 类和方法, 并进行简要说明。
例外情况
异常是一条消息, 用于根据你的喜好显示确切的错误。在Python中, 你可以使用try, 但最后一个关键字来进行错误处理。
如果你不熟悉错误处理, 请转至Pythons错误处理文档以了解错误处理。
让我们看看zipfile模块中的所有异常。
zipfile.BadZipFile
zipfile.BadZipFile是zipfile模块中的异常。错误的Zip文件将引发此错误。请参见下面的示例。
## zipfile.BadZipFile
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file: # opening the zip file using 'zipfile.ZipFile' class
print("Ok")
except zipfile.BadZipFile: # if the zip file has any errors then it prints the error message which you wrote under the 'except' block
print('Error: Zip file is corrupted')
if __name__ == '__main__': main()
## I used a badfile for the test
Ok
zipfile.LargeZipFile
假设如果要使用大型Zip文件, 则需要在打开Zip时启用ZIP64功能。如果你不启用它, LargeZipFile将提高。参见示例。
## zipfile.LargeZipFile
## Without enabling 'Zip64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip') as file:
print('File size is compatible')
except zipfile.LargeZipFile: # it raises an 'LargeZipFile' error because you didn't enable the 'Zip64'
print('Error: File size if too large')
if __name__ == '__main__': main()
File size is compatible
## zipfile.LargeZipFile
## With enabling 'ZIP64'
import zipfile
def main():
try:
with zipfile.ZipFile('sample_file.zip', mode = 'r', allowZip64 = True) as file: # here enabling the 'Zip64'
print('File size is compatible')
except zipfile.LargeZipFile:
print('Error: File size if too large') # if the file size is too large to open it prints the error you have written
if __name__ == '__main__': main()
File size is compatible
选择最适合异常处理的Zip文件, 然后尝试运行该程序。你将获得一个清晰的想法。
类
简而言之, 类是一组方法和属性。通过创建类的实例, 可以在任何需要的地方使用类方法和属性。
让我们看一下zipfile模块的一些类。
zipfile.ZipFile
用于Zip文件的最常见的类是ZipFile类。
zipfile.ZipFile用于写入和读取Zip文件。它具有一些用于处理Zip文件的方法。
现在, 使用dir()对象探索ZipFile类的方法。参见代码。
import zipfile
print(dir(zipfile.ZipFile)) # accessing the 'ZipFile' class
['_RealGetContents', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_extract_member', '_fpclose', '_open_to_write', '_sanitize_windows_name', '_windows_illegal_name_trans_table', '_write_end_record', '_writecheck', 'close', 'comment', 'extract', 'extractall', 'fp', 'getinfo', 'infolist', 'namelist', 'open', 'printdir', 'read', 'setpassword', 'testzip', 'write', 'writestr']
在前面的示例中, 你已经使用zipfile.ZipFile类读取Zip文件。
zipfile.ZipFile包含许多方法(例如解压缩, 打开getinfo, setpassword等)来处理Zip文件。
让我们看一下ZipFile类的一些方法。
## zipfile.ZipFile
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# ZipFile.infolist() returns a list containing all the members of an archive file
print(file.infolist())
# ZipFile.namelist() returns a list containing all the members with names of an archive file
print(file.namelist())
# ZipFile.getinfo(path = filepath) returns the information about a member of Zip file.
# It raises a KeyError if it doesn't contain the mentioned file
print(file.getinfo(file.namelist()[-1]))
# ZipFile.open(path = filepath, mode = mode_type, pwd = password) opens the members of an archive file
# 'pwd' is optional -> if it has password mention otherwise leave it
text_file = file.open(name = file.namelist()[-1], mode = 'r')
# 'read()' method of the file prints all the content of the file. You see this method in file handling.
print(text_file.read())
# You must close the file if you don't open a file using 'with' keyword
# 'close()' method is used to close the file
text_file.close()
# ZipFile.extractall(path = filepath, pwd = password) extracts all the files to current directory
file.extractall()
# after executing check the directory to see extracted files
if __name__ == '__main__': main()
[<ZipInfo filename='extra_file.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='READ ME.txt' filemode='-rw-rw-rw-' file_size=59>, <ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>]
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>
b"num = int(input('Enter a Number:- '))\r\nif num % 2 == 0:\r\n\tprint('{} is Even'.fromat(num))\r\nelse:\r\n\tprint('{} is Odd'.fromat(num))"
如果要学习ZipFile类的所有方法, 请对要学习的方法使用help()函数。
或者转到Python的官方文档进行学习。
zipfile.ZipInfo
zipfile.ZipInfo类, 用于表示Zip文件夹的成员。
首先, 使用dir()方法浏览zipfile.ZipInfo类的所有对象。请参见下面的代码。
## zipfile.ZipInfo
import zipfile
print(dir(zipfile.ZipInfo))
['CRC', 'FileHeader', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_decodeExtra', '_encodeFilenameFlags', '_raw_time', 'comment', 'compress_size', 'compress_type', 'create_system', 'create_version', 'date_time', 'external_attr', 'extra', 'extract_version', 'file_size', 'filename', 'flag_bits', 'from_file', 'header_offset', 'internal_attr', 'is_dir', 'orig_filename', 'reserved', 'volume']
现在, 你将看到zipfile.ZipInfo类的一些方法
## zipfile.ZipInfo
import zipfile
def main():
with zipfile.ZipFile('sample_file.zip') as file:
# 'infolist()' is the object of 'ZipFile' class
# 'infolist()' returns a list containing all the folders and files of the zip -> 'ZipInfo' objects
# assigning last element of the list to a variable to test all the methods of 'ZipInfo'
archive = file.infolist()
read_me_file = archive[-1]
# 'ZipInfo' methods
# ZipInfo_object.filename returns the name of the file
print("Name of the file:- {}".format(read_me_file.filename))
# ZipInfo_object.file_size returns the size of the file
print("Size of the file:- {}".format(read_me_file.file_size))
# ZipInfo_object.is_dir() returns True if it's directory otherwise False
print("Is directory:- {}".format(read_me_file.is_dir()))
# ZipInfo_object.date_time() returns the created date & time of file
print("File created data & time:- {}".format(read_me_file.date_time))
if __name__ == '__main__': main()
Name of the file:- sample_file/READ ME.txt
Size of the file:- 59
Is directory:- False
File created data & time:- (2018, 10, 4, 11, 32, 22)
如果你想了解有关ZipInfo对象的更多信息, 请转到ZipInfo。
方法
方法是程序中特定功能的代码块。例如, 如果要查找数字的绝对值, 则可以使用称为abs的Pythons方法。
你可以在任何需要的地方使用它。让我们看看zipfile模块的一些方法。
zipfile.is_zipfile()
如果文件是有效的Zip, 则zipfile模块的is_zipfile(filename)方法返回True, 否则返回False。
让我们来看一个例子。
## zipfile.is_zip(filename)
import zipfile
def main():
print(zipfile.is_zipfile('sample_file.zip')) # it returns True
if __name__ == '__main__': main()
True
处理Zip文件
在本节中, 你将学习如何处理Zip文件, 例如打开, 提取, 编写等。
提取一个Zip文件
使用extractall方法将Zip文件的文件提取到当前目录。
## extracting zip file
import zipfile
def main():
# assigning filename to a variable
file_name = 'sample_file.zip'
# opening Zip using 'with' keyword in read mode
with zipfile.ZipFile(file_name, 'r') as file:
# printing all the information of archive file contents using 'printdir' method
print(file.printdir())
# extracting the files using 'extracall' method
print('Extracting all files...')
file.extractall()
print('Done!') # check your directory of zip file to see the extracted files
if __name__ == '__main__': main()
File Name Modified Size
sample_file/ 2018-10-04 11:33:22 0
sample_file/even_odd.py 2018-06-29 23:35:54 129
sample_file/READ ME.txt 2018-10-04 11:32:22 59
None
Extracting all files...
Done!
使用密码提取一个邮编
要使用密码提取邮政编码, 你需要将值传递给extract(pwd = password)或extractall(pwd = password)方法的pwd位置参数。
你必须传递以字节为单位的密码。要将str转换为字节, 请使用utf-8编码格式的Python内置方法byte。
让我们来看一个例子。
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'srcmini'
with zipfile.ZipFile(file_name) as file:
# password you pass must be in the bytes you converted 'str' into 'bytes'
file.extractall(pwd = bytes(pswd, 'utf-8'))
if __name__ == '__main__': main()
你还可以使用ZipFile类的setpassword(pwd = password)方法提取文件。请参见下面的示例。
## extracting zip with password
import zipfile
def main():
file_name = 'pswd_file.zip'
pswd = 'srcmini'
with zipfile.ZipFile(file_name) as file:
# 'setpassword' method is used to give a password to the 'Zip'
file.setpassword(pwd = bytes(pswd, 'utf-8'))
file.extractall()
if __name__ == '__main__': main()
创建Zip文件
要创建一个Zip文件, 你不需要任何其他方法。只需将名称传递给ZipFile类, 它将在当前目录中创建一个存档。
请参见以下示例。
## Creating Zip file
import zipfile
def main():
archive_name = 'example_file.zip'
# below one line of code will create a 'Zip' in the current working directory
with zipfile.ZipFile(archive_name, 'w') as file:
print("{} is created.".format(archive_name))
if __name__ == '__main__': main()
example_file.zip is created.
写入Zip文件
你必须以写入模式打开Zip文件, 才能将文件写入存档文件。它会覆盖Zip中的所有现有文件。
举个例子。
## Writing files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# Opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'w') as file:
# write mode overrides all the existing files in the 'Zip.'
# you have to create the file which you have to write to the 'Zip.'
file.write('extra_file.txt')
print('File overrides the existing files')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
File overrides the existing files
['extra_file.txt']
将文件追加到Zip
你必须以append(a)模式打开Zip才能将任何文件附加到Zip。它不会覆盖现有文件。
让我们来看一个例子。
## Appending files to zip
import zipfile
def main():
file_name = 'sample_file.zip'
# opening the 'Zip' in writing mode
with zipfile.ZipFile(file_name, 'a') as file:
# append mode adds files to the 'Zip'
# you have to create the files which you have to add to the 'Zip'
file.write('READ ME.txt')
file.write('even_odd.py')
print('Files added to the Zip')
# opening the 'Zip' in reading mode to check
with zipfile.ZipFile(file_name, 'r') as file:
print(file.namelist())
if __name__ == '__main__': main()
Files added to the Zip
['extra_file.txt', 'READ ME.txt', 'even_odd.py']
到目前为止, 你已经了解了如何处理Zip文件。现在, 你将能够打开, 编写, 附加, 提取, 创建等Zip文件。现在, 你将要编写一个简单的程序。
让我们看看它是什么?
使用循环和zipfile使用密码提取多个子邮政编码
- 你有一个Zip, 其中包含一些子Zip文件。每个Zip文件都有一个密码, 即它们的名称。我们的挑战是解压缩所有Zip, 直到到达终点为止。
解决问题的步骤
- 使用其名称作为密码提取父文件文件。
- 使用namelist()方法获取第一个子名称。将其存储在变量中。
运行循环无限次。
使用is_zipfile()方法检查文件是否为Zip。如果是, 请执行以下操作。
- 用name变量打开zip。
- 从名称变量获取邮政编码的密码。
- 提取邮政编码。
- 获取下一个邮政编码名称并将其存储在名称变量中。
其他
- 使用break中断循环。
我创建了上面的过程。如果需要, 可以根据文件排列进行更改。
## Solution
import zipfile
def main():
# storing the parent name
parent_file_name = '000.zip'
with zipfile.ZipFile(parent_file_name, 'r') as parent_file:
# extracting the parent file
pswd = bytes(parent_file_name.split('.')[0], 'utf-8')
parent_file.extractall(pwd = pswd)
# getting the first child
next_zip_name = parent_file.namelist()[0]
# looping through the sub zips infinite times until you don't encouter a 'Zip' file
while True:
if zipfile.is_zipfile(next_zip_name):
# opening the zip
with zipfile.ZipFile(next_zip_name, 'r') as child_file:
# getting password from the zip name
pswd = bytes(next_zip_name.split('.')[0], 'utf-8')
# extracting the zip
child_file.extractall(pwd = pswd)
# getting the child zip name
next_zip_name = child_file.namelist()[0]
else:
break
if __name__ == '__main__': main()
执行完上述程序后, 你将看到所有子zip均被解压缩到当前目录。
尾注
恭喜你完成了本教程!
希望你喜欢本教程。当你使用Zip文件时, 本文对你有很大帮助。现在, 你可以使用Zip文件了。
如果你对本文有任何疑问, 请在评论部分中问我。我会尽快回复。
同样, 如果你不熟悉Python, 请参加srcmini的免费数据科学入门Python课程, 以学习Python语言或阅读Python的官方文档。
编码愉快!
评论前必须登录!
注册