Python3 Flask在服务器内存中上载文件

Python3 Flask在服务器内存中上载文件,python,file,python-3.x,memory,flask,Python,File,Python 3.x,Memory,Flask,我使用Python3中的Flask作为Web服务器,并使用Flask的上传功能。将文件上载到服务器会产生一个werkzeug.datastructures.FileStorage对象 我需要这个文件的其中一个函数,也需要能够从路径对象打开文件,所以目前,我正在使用open(file\u to\u open)。如果可能的话,我希望避免将上传的文件写入临时文件,只是为了再次读取。因此,我的问题由两部分组成: 1:是否可以将此文件存储对象“转换”为文件对象 2:如果是这样,这是否也适用于当前代码(打开

我使用Python3中的Flask作为Web服务器,并使用Flask的上传功能。将文件上载到服务器会产生一个
werkzeug.datastructures.FileStorage
对象

我需要这个文件的其中一个函数,也需要能够从路径对象打开文件,所以目前,我正在使用
open(file\u to\u open)
。如果可能的话,我希望避免将上传的文件写入临时文件,只是为了再次读取。因此,我的问题由两部分组成:

1:是否可以将此文件存储对象“转换”为文件对象


2:如果是这样,这是否也适用于当前代码(
打开(文件到打开)
)?

您可以将上载的文件存储到。这样,它们仍然是常规文件,无法使用
open()

打开,您可以将上载的文件存储到其中。这样一来,它们仍然是常规文件,无法用
open()

打开。传入的文件上载确实显示为
文件存储
对象。但是,这并不一定意味着涉及实际的物理文件

解析文件对象时,Werkzeug使用
流\u工厂()
可调用来生成文件对象。默认实现仅为500kb及以上的文件创建实际物理文件,以避免占用内存

对于较小的文件,将使用内存中的文件对象

我不会改变这种安排;由于它现在可以正常工作,所以问题的处理是透明的,只有当文件上传会占用您太多内存时,才会涉及到硬盘

相反,我会修改该函数,使其不需要文件名和/或接受文件对象

如果函数只能将路径或包含的数据作为字符串,则可以通过自省底层
.stream
属性来查看是否需要读取文件:

from werkzeug._compat import BytesIO

filename = data = None
if file_upload.filename is None:
    data = file_upload.read()  # in-memory stream, so read it out.
else:
    filename = file_upload.filename

传入的文件上载确实显示为
FileStorage
对象。但是,这并不一定意味着涉及实际的物理文件

解析文件对象时,Werkzeug使用
流\u工厂()
可调用来生成文件对象。默认实现仅为500kb及以上的文件创建实际物理文件,以避免占用内存

对于较小的文件,将使用内存中的文件对象

我不会改变这种安排;由于它现在可以正常工作,所以问题的处理是透明的,只有当文件上传会占用您太多内存时,才会涉及到硬盘

相反,我会修改该函数,使其不需要文件名和/或接受文件对象

如果函数只能将路径或包含的数据作为字符串,则可以通过自省底层
.stream
属性来查看是否需要读取文件:

from werkzeug._compat import BytesIO

filename = data = None
if file_upload.filename is None:
    data = file_upload.read()  # in-memory stream, so read it out.
else:
    filename = file_upload.filename

我知道这一点,但跨平台(windows)不起作用,对吗?另外,它实际上不是一个特定于python的解决方案(您必须创建一个文件系统并指向它,因此对该文件系统的任何更改都必须导致代码的更改)是的,该解决方案不是“pythonic”的,并且可能在移植到其他平台时出现问题。我知道这一点,但这不会跨平台(windows)工作,对吗?另外,它实际上不是一个特定于python的解决方案(您必须创建一个文件系统并指向它,因此对该文件系统的任何更改都必须导致代码的更改)是的,此解决方案不是“pythonic”的,移植到其他平台可能会有问题。您真的需要
open(file\u to\u open)
?因为
FileStorage
对象本身提供了文件API,所以您可以直接使用它。如果您需要再次读取文件,只需调用
uploaded\u file.seek(0)
。我需要一个能够使用路径以及内存对象从磁盘读取文件的函数。如果这意味着替换
open(file\u to\u open)
,那没关系,只要函数
readfile(file)
可以将文件同时作为路径和文件/任何
FileStorage
都可以转换为为什么不只是从文件对象读取的函数?然后你可以给它一个
FileStorage
对象(
readfile(uploaded\u file)
),它就可以工作了。如果需要对磁盘上的文件使用该函数,请使用
readfile(open(filename))
调用它。函数根据其类型用两种方式解释一个参数(因此
readfile(filename)
readfile(open(filename))
具有相同的效果)设计得不是很好。您真的需要
open(file\u to\u open)
?因为
FileStorage
对象本身提供了文件API,所以您可以直接使用它。如果您需要再次读取文件,只需调用
uploaded\u file.seek(0)
。我需要一个能够使用路径以及内存对象从磁盘读取文件的函数。如果这意味着替换
open(file\u to\u open)
,那没关系,只要函数
readfile(file)
可以将文件同时作为路径和文件/任何
FileStorage
都可以转换为为什么不只是从文件对象读取的函数?然后你可以给它一个
FileStorage
对象(
readfile(uploaded\u file)
),它就可以工作了。如果需要对磁盘上的文件使用该函数,请使用
readfile(open(filename))
调用它。根据一个参数的类型(因此
readfile(filename)
readfile(open(filename))
使用两种方法解释一个参数的函数设计得不是很好。最后,我使用了类似的方法。我更改了函数,这样它就不会在方法中执行
打开(file\u to\u open)
。相反,现在我可以传递它
StringIO((file.stream.read()).decode(“utf-8”)
open(file\u to\u open)
而不只是
file\u to\u open
。在这种情况下,我很幸运它是一根弦,但我猜正如你所说的,与BytesIO,y