【问题标题】:Read file data without saving it in Flask读取文件数据而不将其保存在 Flask 中
【发布时间】:2013-11-29 16:48:33
【问题描述】:

我正在编写我的第一个烧瓶应用程序。我正在处理文件上传,基本上我想要的是读取上传文件的数据/内容而不保存它,然后在结果页面上打印它。是的,我假设用户总是上传一个文本文件。

这是我正在使用的简单上传功能:

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

现在,我正在保存文件,但我需要的是包含文件内容/数据的“a”变量..有什么想法吗?

【问题讨论】:

    标签: python flask


    【解决方案1】:

    FileStorage 包含 stream 字段。这个对象必须扩展 IO 或文件对象,所以它必须包含read 和其他类似的方法。 FileStorage 还扩展了stream 字段对象属性,因此您可以只使用file.read() 而不是file.stream.read()。您也可以使用save 参数和dst 参数作为StringIO 或其他IO 或文件对象将FileStorage.stream 复制到另一个IO 或文件对象。

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

    【讨论】:

    • 快速示例:file = request.files.get('file') filetype = magic.from_buffer(file.read(1024))
    • 嗨@user2480542。我遇到了同样的问题。您能描述一下您是如何阅读客户端上传文件的内容的吗?我正在调用 file.read() 但没有得到任何东西。谢谢!
    • @tmthyjames f = request.files['file'] 将上传的文件(在请求中)放入 var ("f")。然后f.read() 使用上面的代码工作。 print f.read() 什么时候在终端里看到正确的垃圾。希望对您有所帮助。
    • 如果您正在上传文件并且有二进制流,您可以通过将其包装在 TextIOWrapper 中轻松地将其转换为文本流:mystring = TextIOWrapper(binary_stream)
    • f.read() 也没有为我带来任何好处。首先打电话给f.seek(0) 对我有用。
    【解决方案2】:

    如果您想使用标准的 Flask 内容 - 如果上传的文件大小 > 500kb,则无法避免保存临时文件。如果它小于 500kb - 它将使用“BytesIO”,它将文件内容存储在内存中,如果它超过 500kb - 它会将内容存储在 TemporaryFile() 中(如werkzeug documentation 中所述)。在这两种情况下,您的脚本都会阻塞,直到收到整个上传的文件。

    我发现的最简单的解决方法是:

    1) 创建您自己的类文件 IO 类,您可以在其中对传入数据进行所有处理

    2) 在你的脚本中,用你自己的重写 Request 类:

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

    3) 将 Flask 的 request_class 替换为您自己的:

    app.request_class = MyRequest
    

    4) 去喝点啤酒:)

    【讨论】:

      【解决方案3】:

      我分享我的解决方案(假设一切都已配置为连接到烧瓶中的谷歌存储桶)

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

      我的帖子

      Direct to Google Bucket in flask

      【讨论】:

        【解决方案4】:

        我试图做同样的事情,打开一个文本文件(实际上是 Pandas 的 CSV)。不想复制它,只想打开它。 form-WTF 有一个不错的文件浏览器,但随后它会打开文件并生成一个临时文件,并将其呈现为内存流。在引擎盖下做一点工作,

        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) 
        

        【讨论】:

          【解决方案5】:

          我使用 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"])
          

          【讨论】:

            【解决方案6】:

            以@tbicr 的出色回答为基础,最简单的形式归结为:

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

            【讨论】:

              【解决方案7】:

              在函数中

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

              在 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>
              

              【讨论】:

                【解决方案8】:

                如果我们想将内存中的文件转储到磁盘。这段代码可以用

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

                【讨论】:

                  猜你喜欢
                  • 2020-02-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-07-26
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多