简体   繁体   English

读取文件数据而不将其保存在 Flask 中

[英]Read file data without saving it in Flask

I am writing my first flask application.我正在编写我的第一个烧瓶应用程序。 I am dealing with file uploads, and basically what I want is to read the data/content of the uploaded file without saving it and then print it on the resulting page.我正在处理文件上传,基本上我想要的是在不保存的情况下读取上传文件的数据/内容,然后将其打印在结果页面上。 Yes, I am assuming that the user uploads a text file always.是的,我假设用户总是上传一个文本文件。

Here is the simple upload function i am using:这是我正在使用的简单上传功能:

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            a = 'file uploaded'

    return render_template('upload.html', data = a)

Right now, I am saving the file, but what I need is that 'a' variable to contain the content/data of the file .. any ideas?现在,我正在保存文件,但我需要的是“a”变量来包含文件的内容/数据......有什么想法吗?

FileStorage contains stream field. FileStorage包含stream字段。 This object must extend IO or file object, so it must contain read and other similar methods.这个对象必须扩展 IO 或文件对象,所以它必须包含read和其他类似的方法。 FileStorage also extend stream field object attributes, so you can just use file.read() instead file.stream.read() . FileStorage还扩展了stream字段对象属性,因此您可以使用file.read()代替file.stream.read() Also you can use save argument with dst parameter as StringIO or other IO or file object to copy FileStorage.stream to another IO or file object.您也可以使用带有dst参数的save参数作为StringIO或其他 IO 或文件对象将FileStorage.stream复制到另一个 IO 或文件对象。

See documentation: http://flask.pocoo.org/docs/api/#flask.Request.files and http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage .请参阅文档: http : //flask.pocoo.org/docs/api/#flask.Request.fileshttp://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage

If you want to use standard Flask stuff - there's no way to avoid saving a temporary file if the uploaded file size is > 500kb.如果您想使用标准的 Flask 内容 - 如果上传的文件大小 > 500kb,则无法避免保存临时文件。 If it's smaller than 500kb - it will use "BytesIO", which stores the file content in memory, and if it's more than 500kb - it stores the contents in TemporaryFile() (as stated in the werkzeug documentation ).如果它小于 500kb - 它将使用“BytesIO”,它将文件内容存储在内存中,如果它超过 500kb - 它会将内容存储在 TemporaryFile() 中(如werkzeug 文档中所述)。 In both cases your script will block until the entirety of uploaded file is received.在这两种情况下,您的脚本都会阻塞,直到收到整个上传的文件。

The easiest way to work around this that I have found is:我发现解决此问题的最简单方法是:

1) Create your own file-like IO class where you do all the processing of the incoming data 1) 创建您自己的类似文件的 IO 类,您可以在其中对传入数据进行所有处理

2) In your script, override Request class with your own: 2)在你的脚本中,用你自己的覆盖请求类:

class MyRequest( Request ):
  def _get_file_stream( self, total_content_length, content_type, filename=None, content_length=None ):
    return MyAwesomeIO( filename, 'w' )

3) Replace Flask's request_class with your own: 3) 用你自己的替换 Flask 的 request_class:

app.request_class = MyRequest

4) Go have some beer :) 4) 去喝点啤酒 :)

I share my solution (assuming everything is already configured to connect to google bucket in flask)我分享我的解决方案(假设一切都已配置为连接到烧瓶中的谷歌存储桶)

from google.cloud import storage

@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        # FileStorage object wrapper
        file = request.files["file"]                    
        if file:
            os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = app.config['GOOGLE_APPLICATION_CREDENTIALS']
            bucket_name = "bucket_name" 
            storage_client = storage.Client()
            bucket = storage_client.bucket(bucket_name)
            # Upload file to Google Bucket
            blob = bucket.blob(file.filename) 
            blob.upload_from_string(file.read())

My post我的帖子

Direct to Google Bucket in flask 直接到 Flask 中的 Google Bucket

I was trying to do the exact same thing, open a text file (a CSV for Pandas actually).我试图做完全相同的事情,打开一个文本文件(实际上是 Pandas 的 CSV)。 Don't want to make a copy of it, just want to open it.不想复制它,只想打开它。 The form-WTF has a nice file browser, but then it opens the file and makes a temporary file, which it presents as a memory stream. form-WTF 有一个不错的文件浏览器,但它会打开文件并创建一个临时文件,将其显示为内存流。 With a little work under the hood,在引擎盖下做一些工作,

form = UploadForm() 
 if form.validate_on_submit(): 
      filename = secure_filename(form.fileContents.data.filename)  
      filestream =  form.fileContents.data 
      filestream.seek(0)
      ef = pd.read_csv( filestream  )
      sr = pd.DataFrame(ef)  
      return render_template('dataframe.html',tables=[sr.to_html(justify='center, classes='table table-bordered table-hover')],titles = [filename], form=form) 

I share my solution, using pandas我分享我的解决方案,使用熊猫


@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        # FileStorage object wrapper
        file = request.files["file"]                    
        if file:
            df = pd.read_excel(files_excel["file"])

Building on a great answer by @tbicr the simplest form of that boils down to:基于@tbicr 的一个很好的答案,最简单的形式归结为:

for line in request.files.get('file'):
   print("Next line: " + line)

I am writing my first flask application.我正在编写我的第一个烧瓶应用程序。 I am dealing with file uploads, and basically what I want is to read the data/content of the uploaded file without saving it and then print it on the resulting page.我正在处理文件上传,基本上我想要的是在不保存的情况下读取上传文件的数据/内容,然后将其打印在结果页面上。 Yes, I am assuming that the user uploads a text file always.是的,我假设用户始终上传一个文本文件。

Here is the simple upload function i am using:这是我正在使用的简单上传功能:

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            a = 'file uploaded'

    return render_template('upload.html', data = a)

Right now, I am saving the file, but what I need is that 'a' variable to contain the content/data of the file .. any ideas?现在,我正在保存文件,但是我需要的是一个'a'变量来包含文件的内容/数据..有什么想法吗?

in function在功能上

def handleUpload():
    if 'photo' in request.files:
        photo = request.files['photo']
        if photo.filename != '':      
            image = request.files['photo']  
            image_string = base64.b64encode(image.read())
            image_string = image_string.decode('utf-8')
            #use this to remove b'...' to get raw string
            return render_template('handleUpload.html',filestring = image_string)
    return render_template('upload.html')

in html file在 html 文件中

<html>
<head>
    <title>Simple file upload using Python Flask</title>
</head>
<body>
    {% if filestring %}
      <h1>Raw image:</h1>
      <h1>{{filestring}}</h1>
      <img src="data:image/png;base64, {{filestring}}" alt="alternate" />.
    {% else %}
      <h1></h1>
    {% endif %}
</body>

In case we want to dump the in memory file to disk.如果我们想将内存文件转储到磁盘。 This code can be used可以使用此代码

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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