Flask:获取 request.files 对象的大小

Posted

技术标签:

【中文标题】Flask:获取 request.files 对象的大小【英文标题】:Flask: Get the size of request.files object 【发布时间】: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']的东西?

【问题讨论】:

【参考方案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 非常大,显然要小心你不会将太多数据读入内存

【讨论】:

***.com/a/23601025/125507 不是更好吗?只是寻找到文件的末尾,你没有使用任何内存? *在文档和来源中:github.com/pallets/werkzeug/blob/master/werkzeug/…【参考方案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 的情况下做同样的事情吗? ***.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

【讨论】:

以上是关于Flask:获取 request.files 对象的大小的主要内容,如果未能解决你的问题,请参考以下文章

flask上传文件时request.files为空的解决办法

PYTHON FLASK - request.files 显示为文件未找到,即使它存在

无法使用 Flask 和 Bootstrap-Vue 表单文件输入从 POST 请求中获取文件

如何从request.FILES获取文件名?

无法获取 request.FILES django

flask服务器端接收文件上传