【问题标题】:How do I create a temporary ZIP in Python 3.x using pyminizip?如何使用 pyminizip 在 Python 3.x 中创建临时 ZIP?
【发布时间】:2019-12-21 16:26:46
【问题描述】:

我需要创建一个临时 zip 文件来存储文件。该 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 文件的工具。这个“双重加密层”是客户的需求,虽然我真的觉得没有必要,但我没有权力从项目中废掉它。 我不习惯处理临时文件。我在这里做错了什么?

【问题讨论】:

  • 看起来可疑的一件事是您将None 传递为srcpath
  • 谢谢马蒂诺!尽管这看起来很奇怪,但在此上下文之外使用的同一行创建了一个功能完善的 zip 文件。我尝试将None 更改为os.getcwd(),但无济于事。

标签: python temporary


【解决方案1】:

使用tempfile-module 可以创建临时文件,这些临时文件在关闭或离开with-block 时会自动删除。使用pyminizip-module 可以得到加密的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-block 时不会自动删除该文件。

因此,使用 tempfile- 和 pyminizip-module 以这种方式 创建临时的、加密的 zip 文件是不可能的。但是,临时文件模块允许创建临时文件以及 临时目录。像临时文件一样,临时目录在离开with-block 时会被删除。如果删除临时目录,则其中包含的文件也将被删除。因此,另一种选择是常见的加密 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,则临时目录连同其中包含的所有加密压缩文件一起被删除。

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

【讨论】:

  • 这听起来不错,但每当我尝试引用destinationFile 时,它​​都会返回错误FileNotFoundError: [Errno 2] No such file or directory: 'destFile.zip'。我尝试使用不同的方法 - zipfile = pyminizip.compress(sourceFile, None, tdir + "\\" + destinationFile, password, compression_level),但每当我尝试从 zipfile 变量中获取任何数据时,它都会返回 None。关于如何将创建的 zip 文件作为字符串读取,如上面的“原始”代码中的任何想法?
  • (1) zip 文件必须在with-block 访问,否则该目录及其内容已经被删除。我粘贴了我的测试程序here。您必须更改源文件的路径 (sourceFile = "C:/Test/src.txt")。生成的压缩文件将在with-block 内成功访问,离开with-block 后访问失败。这适用于我的机器。 (2) 方法zipfile = pyminizip.compress(...必须失败,因为compress总是返回None
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 2022-01-12
  • 2012-07-01
  • 2016-03-15
  • 2018-05-14
相关资源
最近更新 更多