【问题标题】:Flask: Get the size of request.files objectFlask:获取 request.files 对象的大小
【发布时间】:2013-04-02 19:43:40
【问题描述】:

我想获取上传图片的大小来控制它是否大于最大文件上传限制。我试过这个:

@app.route("/new/photo",methods=["POST"])
def newPhoto():

    form_photo = request.files['post-photo']
    print form_photo.content_length

它打印了0。我究竟做错了什么?我应该从它的临时路径中找到这个图像的大小吗? Python中有没有类似PHP的$_FILES['foo']['size']的东西?

【问题讨论】:

    标签: python flask


    【解决方案1】:

    这里有几件事需要注意 - content_length 属性将是浏览器报告的文件上传的内容长度,但不幸的是,许多浏览器不发送此内容,如 docs 和 @987654322 中所述@。

    至于您的 TypeError,接下来要注意的是,小于 500KB 的文件上传以StringIO object 的形式存储在内存中,而不是假脱机到磁盘(再次参见那些文档),因此您的 stat 调用将失败。

    MAX_CONTENT_LENGTH 是拒绝大于您想要的文件上传的正确方法,如果您需要它,确定数据长度的唯一可靠方法是在您处理上传后找出它 - 要么统计.save()d 之后的文件:

    request.files['file'].save('/tmp/foo')
    size = os.stat('/tmp/foo').st_size
    

    或者,如果您不使用磁盘(例如将其存储在数据库中),请计算您已读取的字节数:

    blob = request.files['file'].read()
    size = len(blob)
    

    如果你的 MAX_CONTENT_LENGTH 非常大,显然要小心你不会将太多数据读入内存

    【讨论】:

    【解决方案2】:

    如果您不想先将文件保存到磁盘,请使用以下代码,这适用于内存流

    import os
    
    file = request.files['file']
    file.seek(0, os.SEEK_END)
    file_length = file.tell()
    

    否则这样会更好

    request.files['file'].save('/tmp/file')
    file_length = os.stat('/tmp/file').st_size
    

    【讨论】:

    • file.seek(0, 2) 应该在不导入 os 的情况下做同样的事情吗? stackoverflow.com/a/283719/125507 从文件末尾寻找到 0 个字节
    • 警告:如果您在使用上面的file.seek(0, os.SEEK_END) 选项后尝试保存上传的文件,您上传的文件将被损坏,或者它会是一个空文件。获得 file_length 值后,添加以下内容:file.seek(0, 0)
    【解决方案3】:

    设置最大文件上传限制的正确方法是通过MAX_CONTENT_LENGTH 应用配置。例如,如果您想设置 16 MB 的上传限制,您可以对您的应用配置执行以下操作:

    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
    

    如果上传的文件太大,Flask 会自动返回状态码 413 Request Entity Too Large - 这个应该在客户端处理。

    【讨论】:

    • 好的,这是个好方法。还是没有办法获取图片大小?
    • 这很好,除非您的系统在一个小驱动器上,并且您希望用户上传任何大小的文件,除非它超过可用空间。在这种情况下,请使用 Steely Wing 建议的 file.seek()
    • 更改应用配置可能会导致问题,如果我们想对每个请求设置不同的限制文件大小,例如上传文件 = 2mb,上传照片 = 500kb。
    • 应用规模的配置上传限制不是一个“正确的方式”,只是你应该设置在一切之上。但是,对于不同的文件目的,您仍然可以有不同的文件限制。此外,您可能会根据大小将文件放在不同的驱动器上进行动态存储放置/放大......等等......
    【解决方案4】:

    以下代码部分应该符合您的目的..

    form_photo.seek(0,2) 尺寸 = form_photo.tell()

    【讨论】:

      【解决方案5】:

      正如其他人已经建议的那样,您应该使用

      app.config['MAX_CONTENT_LENGTH'] 
      

      限制文件大小。但 由于您特别想找出图像大小,您可以这样做:

      import os
      photo_size = os.stat(request.files['post-photo']).st_size
      print photo_size
      

      【讨论】:

      • 现在它说 TypeError: coercing to Unicode: need string or buffer, FileStorage found。我该怎么办?
      • request.files 不包含路径。
      【解决方案6】:

      你可以通过 popen from os import

      先保存

      photo=request.files['post-photo']
      photo.save('tmp')
      

      现在,只需获取尺寸

      os.popen('ls -l tmp | cut -d " " -f5').read()
      
      • 以字节为单位
      • 对于兆字节或千兆字节,使用标志 --b M--b G

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-20
        相关资源
        最近更新 更多