问题描述
我有简单的Django视图,用于从Amazon s3下载文件。
在本地保存文件的测试是否正确:
I have simple Django view, for downloading file from Amazon s3.Test by saving file locally was alright:
def some_view(request):
res = s3.get_object(...)
try:
s3_file_content = res['Body'].read()
with open("/Users/yanik/ololo.jpg", 'wb') as f:
f.write(s3_file_content)
# file saved and I can view it
except:
pass
切换到 StreamingHttpResponse
我的文件格式不正确(无法打开)甚至错误的大小(如果原始的是317kb的图像输出木头在大约620kb)
When switch to StreamingHttpResponse
I got incorrect file format (can't open) and even wrong size (If original is 317kb image the output wood be around 620kb)
def some_view(request):
res = s3.get_object(...)
response = StreamingHttpResponse(res['Body'].read(), content_type=res['ContentType'])
response['Content-Disposition'] = 'attachment;filename=' + 'ololo.jpg'
response['ContentLength'] = res['ContentLength']
return response
尝试了许多不同的设置,但到目前为止没有什么对我有用。输出文件已损坏。
Tried many different setting, but so far nothing worked for me. The output file is broken.
我设法获得更多的首个信息。如果我将第一个样本中的文件写入方法从'wb'
更改为'w'
模式,我将具有相同的输出与 StreamingHttpResponse
(第一个视图将生成相同的破碎文件)。
所以看起来我必须告诉http头,我的输出是在二进制
格式
I managed to get more debuting information. If I change my file writing method in first sample from 'wb'
to 'w'
mode I'll have same output as with StreamingHttpResponse
(first view will generate same broken file).So it looks like I must tell http header that my output is on binary
format
现在我明白了问题。 但仍然没有解决方案。
res ['Body']。read()
返回字节
类型和 StreamingHttpResponse
遍历这些字节,返回字节码。所以我漂亮的输入字节'... \x05cgr\xb8 =:\xd0\xc3\x97U\xf4\xf3\xdc\xf0 * \xd4 @ \\ \\ xff\xd9'
强制转换为数组,如: [...,195,151,85,244,243,220,240,42,212, 255,217]
,然后像串联字符串一样下载。截图:
如你所见,最后的列表元素。
Now I'm understand the problem. But still don't have the solution.The res['Body'].read()
returns bytes
type and StreamingHttpResponse
iterate through these bytes, which returns byte codes. So my pretty incoming bytes '...\x05cgr\xb8=:\xd0\xc3\x97U\xf4\xf3\xdc\xf0*\xd4@\xff\xd9'
force converted to array like: [ ... , 195, 151, 85, 244, 243, 220, 240, 42, 212, 64, 255, 217]
and then downloaded like concatenated strings. Screenshot: http://take.ms/JQztkAs you see, the list elements in the end.
StreamingHttpResponse.make_bytes
"""Turn a value into a bytestring encoded in the output charset."""
推荐答案
StreamingHttpResponse需要一个迭代器。我想如果你的文件是二进制(image),那么StreamingHttpResponse不是最好的解决方案,或者你应该创建这个文件的块。
StreamingHttpResponse needs an iterator. I think if your file is binary (image), then StreamingHttpResponse is not the best solution, or you should create chunks of that file.
Bytearray是一个迭代器,但也许你想要去不是字节/字符的行。
Bytearray is an iterator but perhaps you want to go on lines not on bytes/characters.
我不知道你的文件是否是基于行的文本数据,但如果是,你可以创建一个生成器为了迭代文件像对象:
I'm not sure if your file is line based text data, but if it is, you could create a generator in order to iterate over the file like object:
def line_generator(file_like_obj):
for line in file_like_obj:
yield line
,并将该生成器提供给StreamingHttpResponse:
and feed that generator to the StreamingHttpResponse:
some_view(request):
res = s3.get_object(...)
response = StreamingHttpResponse(line_generator(res['Body']), ...)
return response
这篇关于Django StreamingHttpResponse格式错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!