Flask FileStorage 保存空文件
Flask FileStorage save empty file
我正在使用 Flask、WTForms 和 Flask-WTF 保存文件,但文件始终存储为空文件。它没有显示任何错误。
形式:
from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from wtforms import StringField, SubmitField
class UserForm(FlaskForm):
username = StringField('u', validators=[InputRequired()])
email = StringField('e', validators=[InputRequired()])
password = StringField('c', validators=[InputRequired()])
signature = FileField('s')
save = SubmitField('a')
Flask 路线/功能:
@bp.route('/manage/user', methods=['GET', 'POST'])
@login_required
def manage_user():
form = UserForm()
action = 'create'
try:
if form.validate_on_submit():
if form.save.data:
print('request.method', request.method)
print('request.args', request.args)
print('request.form', request.form)
print('request.files', request.files)
# archivo = request.files['signature']
# archivo = request.files.items()[0]
archivo = form.signature.data
print(type(archivo))
if archivo:
image_data = archivo.read()
basedir = os.path.abspath(os.path.dirname(__file__))
filename = secure_filename(form.username.data+'.png')
full_dir = os.path.join(basedir, '..\static\img', filename)
print(sys.getsizeof(archivo))
archivo.save(full_dir)
return redirect(url_for('main.manage'))
except Exception as e:
print(e)
return render_template('manage_user.html', title=('Admon'), form=form, action=action)
HTML
<form action="" method="POST" role="form" class="form-horizontal" enctype="multipart/form-data">
{{ form.csrf_token() }}
<div class="form-group">
<label class="control-label col-sm-3">Firma</label>
<div class="col-sm-6">
{% if action=='create' %}
<!-- Other fields -->
{{ form.signature(placeholder="Firma", type="file", class="form-control", accept="image/*", required="True") }}
<img id="firmaimg" src="{{ url_for('static', filename='img/firma130x50_dummy.png') }}" alt="Firma" />
{{ form.save(class="btn btn-success btn-md") }}
{% endif %}
</div>
</div>
</form>
打印语句显示:
打印的顺序是:
- 请求方式
- 请求参数
- 申请表
- 请求文件
- 存档变量的类型
archivo 的大小总是 32,无论我上传什么图像,总是 32,所以从那时起就已经是空的,不知道为什么会变空。我正在按照示例进行操作。
首先,您的文件大小始终为 32,因为 sys.getsizeof() returns Python 用于该对象的内存量(以字节为单位),如 docs.
要打印您可以使用的实际文件大小:
os.path.getsize('path')
使用它,您应该看到打印的文件大小实际上为 0。
其次,删除:
image_data = archivio.read()
您应该能够成功地将文件保存到所需位置。
我不确定你想用 archivio.read() 完成什么。
对于刚刚偶然发现这个的任何人,
当您对同一个文件对象执行 save() 和 read() 时会出现此错误。
我通过检查 2 个场景扩展了我的研究:
1.read() 在保存之前()
read() 函数将读取文件并将光标置于文件末尾。如果现在保存此对象,它将为空。
2。在读取()之前保存()
成功保存()文件后,文件对象变为空。如果您现在尝试阅读它,您将得到一个空字符串 ''
3。深度复制此文件对象,以便对单独的文件对象执行 read() 和 save()
不允许。某些文件类型(例如 FileStorage)无法进行深度复制。参考 this answer
解决方法
根据 Naisarg 在 中的评论:
在后台保存文件。
file = request.files['file']
file.save(secure_filename(file.filename))
读取该文件。
将该文件附加到第 3 方 API。
r = requests.post(url, headers=headers, data=payload, files={'file': (file.filename, open(file.filename, 'rb'), file.content_type)})
在后台删除文件。
os.remove(file.filename)
我正在使用 Flask、WTForms 和 Flask-WTF 保存文件,但文件始终存储为空文件。它没有显示任何错误。
形式:
from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from wtforms import StringField, SubmitField
class UserForm(FlaskForm):
username = StringField('u', validators=[InputRequired()])
email = StringField('e', validators=[InputRequired()])
password = StringField('c', validators=[InputRequired()])
signature = FileField('s')
save = SubmitField('a')
Flask 路线/功能:
@bp.route('/manage/user', methods=['GET', 'POST'])
@login_required
def manage_user():
form = UserForm()
action = 'create'
try:
if form.validate_on_submit():
if form.save.data:
print('request.method', request.method)
print('request.args', request.args)
print('request.form', request.form)
print('request.files', request.files)
# archivo = request.files['signature']
# archivo = request.files.items()[0]
archivo = form.signature.data
print(type(archivo))
if archivo:
image_data = archivo.read()
basedir = os.path.abspath(os.path.dirname(__file__))
filename = secure_filename(form.username.data+'.png')
full_dir = os.path.join(basedir, '..\static\img', filename)
print(sys.getsizeof(archivo))
archivo.save(full_dir)
return redirect(url_for('main.manage'))
except Exception as e:
print(e)
return render_template('manage_user.html', title=('Admon'), form=form, action=action)
HTML
<form action="" method="POST" role="form" class="form-horizontal" enctype="multipart/form-data">
{{ form.csrf_token() }}
<div class="form-group">
<label class="control-label col-sm-3">Firma</label>
<div class="col-sm-6">
{% if action=='create' %}
<!-- Other fields -->
{{ form.signature(placeholder="Firma", type="file", class="form-control", accept="image/*", required="True") }}
<img id="firmaimg" src="{{ url_for('static', filename='img/firma130x50_dummy.png') }}" alt="Firma" />
{{ form.save(class="btn btn-success btn-md") }}
{% endif %}
</div>
</div>
</form>
打印语句显示:
打印的顺序是:
- 请求方式
- 请求参数
- 申请表
- 请求文件
- 存档变量的类型
archivo 的大小总是 32,无论我上传什么图像,总是 32,所以从那时起就已经是空的,不知道为什么会变空。我正在按照示例进行操作。
首先,您的文件大小始终为 32,因为 sys.getsizeof() returns Python 用于该对象的内存量(以字节为单位),如 docs.
要打印您可以使用的实际文件大小:
os.path.getsize('path')
使用它,您应该看到打印的文件大小实际上为 0。
其次,删除:
image_data = archivio.read()
您应该能够成功地将文件保存到所需位置。
我不确定你想用 archivio.read() 完成什么。
对于刚刚偶然发现这个的任何人,
当您对同一个文件对象执行 save() 和 read() 时会出现此错误。
我通过检查 2 个场景扩展了我的研究:
1.read() 在保存之前()
read() 函数将读取文件并将光标置于文件末尾。如果现在保存此对象,它将为空。
2。在读取()之前保存()
成功保存()文件后,文件对象变为空。如果您现在尝试阅读它,您将得到一个空字符串 ''
3。深度复制此文件对象,以便对单独的文件对象执行 read() 和 save()
不允许。某些文件类型(例如 FileStorage)无法进行深度复制。参考 this answer
解决方法
根据 Naisarg 在
在后台保存文件。
file = request.files['file']
file.save(secure_filename(file.filename))
读取该文件。
将该文件附加到第 3 方 API。
r = requests.post(url, headers=headers, data=payload, files={'file': (file.filename, open(file.filename, 'rb'), file.content_type)})
在后台删除文件。
os.remove(file.filename)