djangocelery 队列中redis文件的存储与下载

vh0rcniy  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(334)

我正在压缩我的应用程序中的大量文件,这会导致性能问题。所以现在我决定将文件压缩到一个单独的队列中,将结果存储在redis中,并在处理完成后立即提供给用户。我在redis中存储数据是为了更快,因为我不需要将文件存储在服务器硬盘上。
这是我的任务.py:

@shared_task
def zip_files(filenames, key):
  compression = zipfile.ZIP_STORED
  s = BytesIO()
  zf = zipfile.ZipFile(s, mode="w")
  for fpath in filenames:
      fdir, fname = os.path.split(fpath)
      zf.write(fpath, fname, compress_type=compression)
  zf.close()
  caches['redis'].set(hash_key, {'file':s.getvalue()})
  return hash_key

下面是我的简单下载视图:

def folder_cache(request, folder_hash):
   cache_data = caches['redis'].get(folder_hash)
   if cache_data:
      response = FileResponse(cache_data['file'], content_type="application/x-zip-compressed")
      response['Content-Disposition'] = 'attachment; filename=hello.zip' 
      response['Content-Length'] = len(cache_data['file'])
      return response
  return HttpResponse("Cache expired.")

问题是我只能下载文件的一部分,然后下载被“网络连接丢失”消息停止。下载的文件似乎包含一组数字(不是二进制数据)。但我不知道,也许我用fileresponse错了?或者我需要在将数据放入redis缓存之前/之后序列化数据?
我在shell中也尝试了同样的代码,当我使用fopen并将redis缓存中的数据直接写入服务器硬盘时,它就可以工作了。

mrfwxfqh

mrfwxfqh1#

最后,我发现我只需要将文件数据 Package 到contentfile类中。下面是最新的工作代码:

def folder_cache(request, folder_hash):
    cache_data = caches['redis'].get(folder_hash)
    if cache_data:
        if (cache_data['status'] == 'complete'):
            ...
            response = FileResponse(ContentFile(cache_data['file']), content_type="application/x-zip-compressed")
            response['Content-Disposition'] = 'attachment; filename={}'.format(filename)
            response['Content-Length'] = len(cache_data['file'])
            return response

相关问题