Загрузка архивов с виртуальной машины занимает слишком много времени, чтобы начать - PullRequest
0 голосов
/ 24 октября 2019

Я написал программу на 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()

Извините, если некоторые вещи не имеют смысла в моем коде, я вставил только ту часть, которая выполняет загрузку. Программа делает намного больше. В любом случае, возможно ли, чтобы загрузка начиналась быстрее?

1 Ответ

1 голос
/ 24 октября 2019

file_download.read() выглядит неправильно. Большинство библиотек HTTP поддерживают потоковую передачу из файлового объекта.

Если make_server равно wsgiref.simple_server.make_server, может сработать следующее, но я не могу это проверить. Идея состоит в том, чтобы не вызывать read напрямую в файл, а использовать wsgiref.util.FileWrapper для преобразования его в итератор блоков. А затем верните этот итератор из функции приложения.

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()

Обратите внимание, что есть два изменения. Отмечено # ***

...