18.6. 文件归档、加密和解密

学习大纲:

  • 创建和解压归档文件。

  • TAR归档文件。

  • 创建ZIP文件。

  • 文件加密与解密。

18.6.1. 1.创建和解压归档文件

1.1 创建归档文件

shutil_make_archive.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import shutil
import sys
import tarfile

shutil.make_archive('work_sample', 'gztar', root_dir='..', base_dir='06', )
print('Archive contents:')

with tarfile.open('work_sample.tar.gz', 'r') as t_file:
    for names in t_file.getnames():
        print(names)

上面的示例程序使用了Python的shutiltarfile 模块创建归档文件。在shutil.make_archive() 中,参数work_sample 指定了归档文件的名称,并且采用gz 格式。然后在base_dir 属性中指定了工作目录的名称。最后程序输出了归档文件的名称。

1.2 解压归档文件

shutil_unpack_archive.py

shutil 模块含有unpack_archive() 函数,用于解压归档文件。此功能可以提取归档文件的内容。我们只需向函数传递归档文件名称和提取内容的目标目录即可。如果没有传递目标目录名,它会将内容提取到当前工作目录。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pathlib
import shutil
import sys
import tempfile

with tempfile.TemporaryDirectory() as d:
    shutil.unpack_archive("work_sample.tar.gz", extract_dir="./", )
    prefix_len = len(d) + 1

    for extrected in pathlib.Path(d).rglob("*"):
        print(str(extrected)[prefix_len:])

18.6.2. 2.TAR归档文件

check_archive_file.py

tarfile.is_tarfile() 函数判断文件是否是 TAR 文件,如果不存在会抛出异常

tarfile.is_tarfile("hello.tar.gz")  # True

getmembers()方法获取文件的元数据

with tarfile.open("example.tar.gz", 'r') as t_file:
        #getmembers()方法获取文件的元数据
    for m in t_file.getmembers():
        print(m.name)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tarfile
import time

with tarfile.open('work.tar', 'r') as t:
    for file_info in t.getmembers():
        print(file_info.name)
        print("Size   :", file_info.size, 'bytes')
        print("Type   :", file_info.type)
        print()

add() 方法向归档文件中添加文件

with tarfile.open("example.tar.gz", mode='a') as t_file:
    t_file.add("test.txt")

extractall() 方法提取所有内容

#example
with tarfile.open("example.tar.gz", 'r') as file:
    file.extractall("example")

18.6.3. 3.创建ZIP文件

shutil.make_archive() 函数可以创建 ZIP 压缩文件,

zipfile.is_zipfile() 函数判断文件是否是 ZIP 文件

infolist() 方法获取文件元数据

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import shutil
shutil.make_archive('work', 'zip', 'work')
# example
import zipfile
shutil.make_archive( "example_zip", "zip",root_dir = "..", base_dir = "SystemManagerSkills")
zipfile.is_zipfile("example_zip.zip")


with zipfile.ZipFile("example_zip.zip") as z:
    for info in z.infolist():
        print(info.filename)

18.6.4. 4.文件加密与解密

Python的pyAesCrypt 模块。pyAesCrypt 是一个文件加密模块,它使用AES256-CBC 来加密/解密文件和二进制流。

pip install -U pyAesCrypt -i "https://pypi.doubanio.com/simple/"

加密sample.txt 文件,file_encrypt.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyAesCrypt
from os import stat, remove

# 加/解密缓冲区大小—64KB
bufferSize = 64 * 1024
password = "#Training"

with open("sample.txt", "rb") as fIn:
    with open("sample.txt.aes", "wb") as fOut:
        pyAesCrypt.encryptStream(fIn, fOut, password, bufferSize)

# 获得加密的文件大小
encFileSize = stat("sample.txt.aes").st_size

查看当前工作目录,我们可以找到sample.txt.aes 加密文件。

在这个示例程序中,我们指定了缓冲区大小和密码,接着指定了被加密的文件名。在encryptStream() 函数中,fIn 参数表示被加密的文件,fOut 参数表示加密后的文件。加密文件存储为sample.txt.aes

解密sample.txt.aes 文件,以获取文件内容。创建一个脚本,命名为file_decrypt.py ,并在其中添加以下代码。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyAesCrypt
from os import stat, remove

bufferSize = 64 * 1024

password = "#Training"
encFileSize = stat("sample.txt.aes").st_size

with open("sample.txt.aes", "rb") as fIn:
    with open("sampleout.txt", "wb") as fOut:
        try:
            pyAesCrypt.decryptStream(fIn, fOut, password, bufferSize, encFileSize)
        except ValueError:
            remove("sampleout.txt")

with open("sampleout.txt",'r') as f:
    print(f.read())

在这个示例程序中,指定了被解密的文件sample.txt.aes ,然后指定了解密后的文件为sampleout.txt 。在decryptStream() 函数中,fIn 参数表示被解密的文件,fOut 参数表示解密后的文件。

18.6.5. 总结

Python的tarfilezipfile 模块,使用它们能创建和解压归档文件,也能将新文件添加到已有的归档文件中,还能获取元数据,从归档中提取文件的内容。

最后,我们还学习了使用pyAescrypt 模块进行文件加密和解密。