在Python中使用Zip文件

本文概述

  • 例外情况
  • 方法
  • 处理Zip文件
  • 使用循环和zipfile使用密码提取多个子邮政编码
目录
  • 使用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' moduleprint(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 zipfiledef 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 zipfiledef 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 zipfiledef 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 writtenif __name__ == '__main__': main()

File size is compatible

选择最适合异常处理的Zip文件, 然后尝试运行该程序。你将获得一个清晰的想法。
类简而言之, 类是一组方法和属性。通过创建类的实例, 可以在任何需要的地方使用类方法和属性。
让我们看一下zipfile模块的一些类。
zipfile.ZipFile
用于Zip文件的最常见的类是ZipFile类。
zipfile.ZipFile用于写入和读取Zip文件。它具有一些用于处理Zip文件的方法。
现在, 使用dir()对象探索ZipFile类的方法。参见代码。
import zipfileprint(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 zipfiledef 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 filesif __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 zipfileprint(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 zipfiledef 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 zipfiledef main(): print(zipfile.is_zipfile('sample_file.zip')) # it returns Trueif __name__ == '__main__': main()

True

处理Zip文件在本节中, 你将学习如何处理Zip文件, 例如打开, 提取, 编写等。
提取一个Zip文件使用extractall方法将Zip文件的文件提取到当前目录。
## extracting zip file import zipfiledef 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 filesif __name__ == '__main__': main()

File NameModifiedSize sample_file/2018-10-04 11:33:220 sample_file/even_odd.py2018-06-29 23:35:54129 sample_file/READ ME.txt2018-10-04 11:32:2259 None Extracting all files... Done!

使用密码提取一个邮编要使用密码提取邮政编码, 你需要将值传递给extract(pwd = password)或extractall(pwd = password)方法的pwd位置参数。
你必须传递以字节为单位的密码。要将str转换为字节, 请使用utf-8编码格式的Python内置方法byte。
让我们来看一个例子。
## extracting zip with password import zipfiledef 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 zipfiledef 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 zipfiledef 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 zipfiledef 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【在Python中使用Zip文件】你必须以append(a)模式打开Zip才能将任何文件附加到Zip。它不会覆盖现有文件。
让我们来看一个例子。
## Appending files to zip import zipfiledef 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 zipfiledef 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: breakif __name__ == '__main__': main()

执行完上述程序后, 你将看到所有子zip均被解压缩到当前目录。
尾注
恭喜你完成了本教程!
希望你喜欢本教程。当你使用Zip文件时, 本文对你有很大帮助。现在, 你可以使用Zip文件了。
如果你对本文有任何疑问, 请在评论部分中问我。我会尽快回复。
同样, 如果你不熟悉Python, 请参加srcmini的免费数据科学入门Python课程, 以学习Python语言或阅读Python的官方文档。
编码愉快!

    推荐阅读