为什么连续上传同一个文件时会收到空的 InMemoryUploadedFile 对象
我有一个脚本,它会向Django发送一个POST请求来上传文件。这个脚本会一直运行,并上传一个名为“file1.csv”的文件。
files ={"uploadedfile": ("file1.csv", open("file1.csv", 'rb'))}
requests.post(url, files=files)
当Django第一次接收到file1.csv时,我可以读取到文件的内容,而且文件大小不是零。
payload = request.FILES
file = payload['uploadedfile']
print "File size:", file.size
输出:
File size: 1758
但是当我在新的POST请求中第二次接收到这个文件时(因为上传脚本一直在循环运行),文件却是空的。
File size: 0
我不明白这是为什么。有没有什么想法?
我也尝试上传了多个不同的文件。每当同一个文件在第一次之后被上传了n
次,InMemoryUploadedFile对象总是为空。
这是为什么呢?
3 个回答
你的文件大于2.5兆字节吗?
默认情况下,如果你上传的文件小于2.5兆字节,Django会把整个文件内容保存在内存里。这意味着保存文件的时候,只需要从内存读取数据,然后写入磁盘,所以这个过程非常快。
但是,如果你上传的文件太大,Django就会把这个文件写入一个临时文件,存放在你系统的临时目录里。在类Unix系统上,你可以看到Django会生成一个类似于/tmp/tmpzfp6I6.upload的文件。如果上传的文件足够大,你会看到这个文件的大小随着Django把数据写入磁盘而不断增加。
这些具体的数字,比如2.5兆字节,或者/tmp等,只是一些“合理的默认设置”,你可以根据需要进行自定义,具体的做法会在下一部分介绍。
这里有关于Django文件上传的说明。希望对你有帮助。
只需要执行 file.seek(0)
这个命令就可以解决你的问题。
我之前也遇到过类似的问题。这种情况发生在你执行以下代码行一次后
files ={"uploadedfile": ("file1.csv", open("file1.csv", 'rb'))}
然后再执行涉及上传的下一行,且上传次数超过一次。
requests.post(url, files=files)
我猜你是在一个解释器里运行上面的代码,以为可以创建一次 files
字典,然后多次上传。其实这样是行不通的!而且这和Django没有关系。
所以,在每次上传之前,重新创建你的 files
字典,这样就没问题了。