【问题标题】:Read a zip file sent to a flask server without storing it on disk读取发送到烧瓶服务器的 zip 文件,而不将其存储在磁盘上
【发布时间】:2020-06-23 21:34:39
【问题描述】:

我想读取通过表单发布请求发送到烧瓶服务器的特定类型 zip 文件中的所有文件,而无需将 zip 文件存储在磁盘上。

【问题讨论】:

  • 请更具体。
  • 这样更好吗?

标签: python flask zip


【解决方案1】:

首先,获取获取zip文件的代码

from flask import Flask, request
app = Flask(__name__)

@app.route("/",methods=["GET"])
def page_name_get(): 
    return """<form action="." method="post" enctype=multipart/form-data>
        <input type="file" accept="application/zip" name="data_zip_file" accept="application/zip" required>
         <button type="submit">Send zip file!</button>
        </form>"""
app.run()

post 请求函数应该是这样的

import zipfile

@app.route("/",methods=["POST"])
def page_name_post():
    file = request.files['data_zip_file']  
    file_like_object = file.stream._file  
    zipfile_ob = zipfile.ZipFile(file_like_object)
    file_names = zipfile_ob.namelist()
    # Filter names to only include the filetype that you want:
    file_names = [file_name for file_name in file_names if file_name.endswith(".txt")]
    files = [(zipfile_ob.open(name).read(),name) for name in file_names]
    return str(files)

现在我将逐行介绍

file = request.files['data_zip_file'] 首先,您需要从请求中获取文件对象,这是werkzeug.datastructures.FileStorage 类的一个实例。

file_like_object = file.stream._file这里先取werkzeug.datastructures.FileStorage的stream属性,这是文件的输入流。这将返回一个用于临时文件的类tempfile.SpooledTemporaryFile 的实例。从那个实例中,您获取 ._file 属性。这将返回一个tempfile._TemporaryFileWrapper 的实例,这足以让zipfile.ZipFile 类理解io.BytesIO

zipfile_ob = zipfile.ZipFile(file_like_object) 在这里创建zipfile.Zipfile 对象

现在您应该可以使用 zip 完成几乎所有您想做的事情了。要从 zip 中选择文件,请使用 zipfile_ob.open() 方法并传入要打开的文件的路径。

要获取这些路径,我们使用file_names = zipfile_ob.namelist() 这将返回一个列表,其中包含指向 zip 中所有文件和目录的所有路径的字符串。

然后您可以使用 file_names = [file_name for file_name in file_names if file_name.endswith(".txt")] 过滤这些名称

您想要的所有路径现在都在file_names 中。然后您可以使用 open 函数提取这些文件的数据。

files = [(zipfile_ob.open(name).read(),name) for name in file_names]

在给出的示例中,我将文件的路径保留在最终列表中,但如果您不希望这样,您可以使用:

files = [zipfile_ob.open(name).read() for name in file_names] 或使用其他方式检查文件。如果您想了解有关文件的更多信息,还可以使用infolist() 方法代替namelist(),这将返回ZipInfo Objects 列表而不是字符串列表。这些对象包含有关所有文件的更多数据。

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2021-11-21
    • 2023-03-30
    • 2011-03-26
    • 1970-01-01
    相关资源
    最近更新 更多