【问题标题】:Downloading archives from a virtual machine takes too much time to start从虚拟机下载档案需要太多时间才能开始
【发布时间】:2019-10-24 07:22:50
【问题描述】:

我用 Python 编写了一个从虚拟机下载 .tar.gz 存档的程序。下载工作正常,但问题是启动时间过长。这是我处理下载的代码部分:

import os
from wsgiref.util import request_uri
from wsgiref.simple_server import make_server

def download(self,dirr):
     file_url = os.environ['location'] + dirr
     headers = [('Content-Description', 'File Transfer'),
               ('Content-Type', 'application/octet-stream'),
               ('Content-Disposition', 'attachement; filename="'+os.path.basename(file_url)+'"'),
               ('Expires', '0'),
               ('Cache-Control', 'must-revalidate'),
               ('Pragma', 'public'),
               ('Content-Length', str(os.stat(file_url).st_size))]
        
      file_download = open(file_url, 'rb')
      return headers, file_download.read()

def server_app(environ, start_response):
    crt_handler = handler(request_uri(environ))
    headers, response_body = crt_handler.get() // this calls my download function, which is part of a class. 
    status = '200 OK'
    start_response(status, headers)
    return [response_body] 

def start_server():
   httpd = make_server("", PORT, server_app)
   httpd.serve_forever()

抱歉,如果我的代码中有些内容没有意义,我只粘贴了进行下载的部分。该程序做得更多。无论如何,有没有可能让下载开始更快?

【问题讨论】:

  • 下载速度很少受客户端限制,主要受服务器和连接限制。
  • 我的问题不是下载速度,而是启动时间。那还取决于服务器和连接? @克劳斯D。
  • 确实如此。但在您的情况下,它是 您的 服务器。您正在从远程服务器获取整个文件,完成后您将其发送给您的客户端。这就解释了等待时间。您必须实施流式 HTTP 来解决这个问题。

标签: python python-2.7 virtual-machine


【解决方案1】:

file_download.read() 看起来不对。大多数 HTTP 库都支持从文件对象流式传输。

如果make_serverwsgiref.simple_server.make_server,以下可能有效,但我无法测试。这个想法是不直接调用文件read,而是使用wsgiref.util.FileWrapper 将其转换为块的迭代器。然后从 app 函数中返回该迭代器。

def download(self,dirr):
     file_url = os.environ['location'] + dirr
     headers = [('Content-Description', 'File Transfer'),
               ('Content-Type', 'application/octet-stream'),
               ('Content-Disposition', 'attachement; filename="'+os.path.basename(file_url)+'"'),
               ('Expires', '0'),
               ('Cache-Control', 'must-revalidate'),
               ('Pragma', 'public'),
               ('Content-Length', str(os.stat(file_url).st_size))]

      file_download = open(file_url, 'rb')
      return headers, wsgiref.util.FileWrapper(file_download) # ***

def server_app(environ, start_response):
    crt_handler = handler(request_uri(environ))
    headers, response_body = crt_handler.get() // this calls my download function, which is part of a class. 
    status = '200 OK'
    start_response(status, headers)
    return response_body # ***

def start_server():
   httpd = make_server("", PORT, server_app)
   httpd.serve_forever()

注意上面有两个变化。标记为# ***

【讨论】:

  • 是的,make_serverwsgiref.simple_server.make_server,我会编辑我的帖子。
  • 当我尝试返回 wsgiref.util.FileWrapper(file_download) 时遇到错误。 wsgiref\handlers.py", line 204, in write 中的一个错误是 AssertionError: write() argument must be stringwsgiref\simple_server.py", line 33, in close 中的一个错误是 AttributeError: 'NoneType' object has no attribute 'split'
  • 没关系,我忘记返回 response_body 而不是 [response_body]。它的工作原理和下载开始的方式更快。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2012-03-31
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
相关资源
最近更新 更多