How to copy InMemoryUploadedFile object to disk

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

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 ?

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

And the debug :

回答1:

This is 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) 


回答2:

As mentioned by @ups, when uploading large files, you don't want to clog up system memory with a data.read().

From Django docs :

Looping over UploadedFile.chunks() instead of using read() ensures that large files don't overwhelm your system's memory

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_storage will unless told otherwise.



回答3:

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.

Regards



回答4:

Here is another way to do it with python's 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 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!