Python 如何将 InMemoryUploadedFile 对象复制到磁盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3702465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to copy InMemoryUploadedFile object to disk
提问by sasklacz
I am trying to catch a file sent with form and perform some operations on it before it will be saved. So I need to create a copy of this file in temp directory, but I don't know how to reach it. Shutil's functions fail to copy this file, since there is no path to it. So is there a way to do this operation in some other way ?
我正在尝试捕获随表单发送的文件并在保存之前对其执行一些操作。所以我需要在临时目录中创建这个文件的副本,但我不知道如何访问它。由于没有路径,Shutil 的函数无法复制此文件。那么有没有办法以其他方式执行此操作?
My code :
我的代码:
image = form.cleaned_data['image']
temp = os.path.join(settings.PROJECT_PATH, 'tmp')
sourceFile = image.name # without .name here it wasn't working either
import shutil
shutil.copy(sourceFile, temp)
Which raises :
其中提出:
Exception Type: IOError at /
Exception Value: (2, 'No such file or directory')
Exception Type: IOError at /
Exception Value: (2, 'No such file or directory')
And the debug :
和调试:
# (..)\views.py in function
67. sourceFile = image.name
68. import shutil
69. shutil.copy2(sourceFile, temp) ...
# (..)\Python26\lib\shutil.py in copy2
92. """Copy data and all stat info ("cp -p src dst").
93.
94. The destination may be a directory.
95.
96. """
97. if os.path.isdir(dst):
98. dst = os.path.join(dst, os.path.basename(src))
99. copyfile(src, dst) ...
100. copystat(src, dst)
101.
▼ Local vars
Variable Value
dst
u'(..)\tmp\myfile.JPG'
src
u'myfile.JPG'
# (..)\Python26\lib\shutil.py in copyfile
45. """Copy data from src to dst"""
46. if _samefile(src, dst):
47. raise Error, "`%s` and `%s` are the same file" % (src, dst)
48.
49. fsrc = None
50. fdst = None
51. try:
52. fsrc = open(src, 'rb') ...
53. fdst = open(dst, 'wb')
54. copyfileobj(fsrc, fdst)
55. finally:
56. if fdst:
57. fdst.close()
58. if fsrc:
▼ Local vars
Variable Value
dst
u'(..)\tmp\myfile.JPG'
fdst
None
fsrc
None
src
u'myfile.JPG'
采纳答案by Davor Lucic
Thisis similar question, it might help.
这是类似的问题,它可能会有所帮助。
import os
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.conf import settings
data = request.FILES['image'] # or self.files['image'] in your form
path = default_storage.save('tmp/somename.mp3', ContentFile(data.read()))
tmp_file = os.path.join(settings.MEDIA_ROOT, path)
回答by Arthur Debert
Your best course of action is to write a custom Upload handler. See the docs. If you add a "file_complete" handler, you can access the file's content regardless of having a memory file or a temp path file. You can also use the "receive_data_chunck" method and write your copy within it.
您最好的做法是编写自定义上传处理程序。请参阅文档。如果添加“file_complete”处理程序,则无论具有内存文件还是临时路径文件,都可以访问文件的内容。您还可以使用“receive_data_chunck”方法并在其中写入副本。
Regards
问候
回答by David542
Here is another way to do it with python's mkstemp:
这是使用 python 的另一种方法mkstemp:
### get the inmemory file
data = request.FILES.get('file') # get the file from the curl
### write the data to a temp file
tup = tempfile.mkstemp() # make a tmp file
f = os.fdopen(tup[0], 'w') # open the tmp file for writing
f.write(data.read()) # write the tmp file
f.close()
### return the path of the file
filepath = tup[1] # get the filepath
return filepath
回答by Emile Bergeron
As mentioned by @S?awomir Lenart, when uploading large files, you don't want to clog up system memory with a data.read().
正如@S?awomir Lenart所提到的,在上传大文件时,您不想用data.read().
From Django docs:
来自Django 文档:
Looping over
UploadedFile.chunks()instead of usingread()ensures that large files don't overwhelm your system's memory
循环
UploadedFile.chunks()而不是使用read()可确保大文件不会淹没系统内存
from django.core.files.storage import default_storage
filename = "whatever.xyz" # received file name
file_obj = request.data['file']
with default_storage.open('tmp/'+filename, 'wb+') as destination:
for chunk in file_obj.chunks():
destination.write(chunk)
This will save the file at MEDIA_ROOT/tmp/as your default_storagewill unless told otherwise.
除非另有说明,否则这将MEDIA_ROOT/tmp/按照您的意愿保存文件default_storage。
回答by Prasad
This is how I tried to save the file locally
这就是我尝试在本地保存文件的方式
file_object = request.FILES["document_file"]
file_name = str(file_object)
print(f'[INFO] File Name: {file_name}')
with open(file_name, 'wb+') as f:
for chunk in file_object.chunks():
f.write(chunk)

