如何将InMemoryUploadedFile对象复制到磁盘

owc*_*wca 37 python django file-upload file-storage

我试图捕获一个与表单一起发送的文件,并在保存之前对其执行一些操作.所以我需要在临时目录中创建此文件的副本,但我不知道如何到达它.Shutil的功能无法复制此文件,因为没有路径.那么有没有办法以其他方式进行此操作?

我的代码:

    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)
Run Code Online (Sandbox Code Playgroud)

哪个提出:

Exception Type: IOError at /
Exception Value: (2, 'No such file or directory')

调试:

#  (..)\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'
Run Code Online (Sandbox Code Playgroud)

Dav*_*cic 47

是类似的问题,它可能有所帮助.

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)
Run Code Online (Sandbox Code Playgroud)

  • 当您在一个文件中上传许多MB时,问题就开始了.然后使用缓冲.像while循环中的data.read(BUF_SIZE). (2认同)
  • 许多/大是一个相对的度量,并且有许多变量(例如,内存量,磁盘大小,网络类型/速度等),但是对于您可能写入[磁盘块]的大文件是的(https:// docs.djangoproject.com/en/dev/topics/http/file-uploads/). (2认同)

Emi*_*ron 14

正如@ups所提到的,当上传大文件时,你不想用一个阻塞系统内存data.read().

来自Django文档:

循环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)
Run Code Online (Sandbox Code Playgroud)

除非另有说明,否则这将MEDIA_ROOT/tmp/按照您的意愿保存文件default_storage.


Dav*_*542 6

这是使用 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
Run Code Online (Sandbox Code Playgroud)


Art*_*ert 5

您最好的做法是编写自定义上传处理程序.查看文档.如果添加"file_complete"处理程序,则无论是否具有内存文件或临时路径文件,都可以访问该文件的内容.您还可以使用"receive_data_chunck"方法并在其中编写副本.

问候