简体   繁体   中英

Read a zip file sent to a flask server without storing it on disk

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

First, get the code to get the zip file

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()

This is how the post request function should look like

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)

Now I will go over this line by line

file = request.files['data_zip_file'] First, you need to get the file object from the request this is is an instance of the werkzeug.datastructures.FileStorage class.

file_like_object = file.stream._file here you first take the stream attribute of the werkzeug.datastructures.FileStorage this is the input stream of the file. This will return an instance of tempfile.SpooledTemporaryFile a class used for temporary files. From that instance, you take the ._file attribute. This will return an instance of tempfile._TemporaryFileWrapper This is enough like an io.BytesIO to be understood by the zipfile.ZipFile class.

zipfile_ob = zipfile.ZipFile(file_like_object) here you create the zipfile.Zipfile object

Now you should be able to do pretty much everything you would want to do with the zip. To select a file from the zip use the zipfile_ob.open() method and pass in the path to the file you want to open.

To get those paths we use file_names = zipfile_ob.namelist() this will return a list with strings of all the paths to all the files and directories in the zip.

You can then filter those names with file_names = [file_name for file_name in file_names if file_name.endswith(".txt")]

All those paths you want are now in file_names . Then you can extract the data of those files using the open function.

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

In the example given I keep the paths to the file in the final list but if you don't want that you can use:

files = [zipfile_ob.open(name).read() for name in file_names] or use some other way to go over the file. If you want more info about the files there is also the infolist() method that can be used instead of the namelist() this will return a list of ZipInfo Objects instead of a list of just strings. These objects hold some more data about all the files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM