如何使用 pyminizip 在 Python 3.x 中创建临时 ZIP?

How do I create a temporary ZIP in Python 3.x using pyminizip?

我需要创建一个临时压缩文件来存储文件。该 ZIP 文件需要加密,因此 zipfile 在这里不起作用。该文件将被进一步加密(ZIP 将被再次加密成另一个文件),因此压缩文件被用作减小其大小以实现更快的互联网传输以及第一层加密的一种方式。 到目前为止,这是我得到的:

import getpass
import tempfile
import pyminizip

def ZipFunction():
    #This zips the file and encrypts it with a password
    filename = input('Enter the file name: ')
    passkey = getpass.getpass(prompt='Enter the password for the file: ')
    passkey2 = getpass.getpass(prompt='Confirm the password: ')
    if passkey != passkey2:
        print('The passwords must be the same! Please restart the process.')
        exit()
    else:
        #Here's where I need help
        with tempfile.TemporaryFile() as tmp:
            with pyminizip.compress(filename,None,tmp,passkey,9) as archive:
                zipstring = archive.readlines()

        #From here on the zipstring var is encrypted and creates the "further encrypted"
        #file. From here on the script works normally

返回的错误是ValueError: expected arguments are compress(src, srcpath, dst, pass, level)。 我愿意将 pyminizip 更改为另一个可以创建加密 zip 文件的工具。这个 "dual encryption layer" 是客户的需求,虽然我真的不认为有必要,但我没有权力将其从项目中废弃。 我不习惯处理临时文件。我在这里做错了什么?

使用tempfile-module temporary files can be created which are automatically deleted when closing or leaving a with-block. With the pyminizip模块可以获得加密的zip文件。

pyminizip.compress 期望将生成的 zip 文件保存的路径作为第三个参数。如果文件已经存在,则会尝试覆盖它。当前代码使用对临时文件 (tmp) 的引用,这导致观察到的错误消息:

ValueError: expected arguments are compress(src, srcpath, dst, pass, level) 

错误的直接原因是使用了引用本身而不是它的文件名,即为了避免错误,实际上应该使用 tmp.name 而不是 tmp。但是,如果更改此设置,则会生成一条不同的错误消息,即

OSError: error in closing <path to temo file> (-102)                                    

这是因为 pyminizip 模块试图在它仍然打开时删除临时文件。如果之前关闭了临时文件,它将被覆盖而不会出现错误消息。但是,这只会创建一个普通文件而不是临时文件,即当关闭或离开 with-块时,文件不会被自动删除。

因此,无法使用临时文件和 pyminizip 模块以这种方式创建临时的、加密的 zip 文件。然而,临时文件模块允许创建临时文件以及临时目录。与临时文件一样,临时目录在离开 with 块时被删除。如果删除临时目录,则其中包含的文件也将被删除。因此,另一种选择是常见的加密 zip 文件(使用 pyminizip 模块创建),这些文件存储在临时文件夹中(使用 tempfile 模块创建):

...
with tempfile.TemporaryDirectory() as tdir:
    sourceFile = <path to file to be zipped>
    destinationFile = "destFile.zip"
    password = "whatever"
    compression_level = 9 # 1-9
    pyminizip.compress(sourceFile, None, tdir + "\" + destinationFile, password, compression_level)

    # inside with-block: temp-directory and contained encrypted zip-files exist
    ...                     

# outside with-block: temp-directory and contained encrypted zip-files deleted
...                     

如果 with-block 被留下,临时目录连同它包含的任何加密的 zip 文件一起被删除。

顺便说一句:pyminizip.compress 不支持 with 语句。这将导致错误消息:AttributeError: __enter__。在当前代码中您看不到此错误消息,因为发布的错误消息是之前触发的。