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

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

下面是我使用的简单上传功能:

@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’变量来包含文件的内容/数据。.有什么想法吗?

174521 次浏览

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

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

如果你想使用标准的 Flask 东西-没有办法避免保存临时文件,如果上传的文件大小 > 500kb。如果它小于500kb-它将使用“ BytesIO”,它将文件内容存储在内存中,如果它大于500kb-它将内容存储在颞文件()中(如 沃克泽格文件所述)。在这两种情况下,脚本都会阻塞,直到收到完整的上传文件为止。

我发现解决这个问题最简单的方法是:

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)去喝点啤酒:)

如果我们想将内存中的文件转储到磁盘,可以使用下面的代码

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


在功能上

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>

我正在尝试做完全相同的事情,打开一个文本文件(实际上是熊猫的 CSV)。我不想复印,只想打开看看。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)

我分享我的解决方案(假设所有东西都已经配置为连接到烧瓶中的 google bucket)

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

我的岗位

直接到谷歌桶在烧瓶

我分享我的解决方案,用熊猫


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

基于@tbicr 给出的一个很棒的答案,最简单的形式可以归结为:

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