文件切片,每一片都進行異步下載python
影響是增長了文件的下載時間ios
import os import stat import tornado.gen import tornado.httpserver import tornado.ioloop import tornado.web from tornado import iostream class DownloadHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def get(self): file_path = './a.zip' content_length = self.get_content_size(file_path) self.set_header("Content-Length", content_length) self.set_header("Content-Type", "application/octet-stream") self.set_header("Content-Disposition", "attachment;filename=\"{0}\"".format("a.data")) #設置新的文件名 content = self.get_content(file_path) if isinstance(content, bytes): content = [content] for chunk in content: try: self.write(chunk) yield self.flush() except iostream.StreamClosedError: break return # 使用python自帶的對於yield的應用對文件進行切片,for循環每運用一次就調用一次 def get_content(self, file_path): start=None end=None with open(file_path, "rb") as file: if start is not None: file.seek(start) if end is not None: remaining = end - (start or 0) else: remaining = None while True: chunk_size = 64 * 1024 #每片的大小是64K if remaining is not None and remaining < chunk_size: chunk_size = remaining chunk = file.read(chunk_size) if chunk: if remaining is not None: remaining -= len(chunk) yield chunk else: if remaining is not None: assert remaining == 0 return # 讀取文件長度 def get_content_size(self, file_path): stat_result = os.stat(file_path) content_size = stat_result[stat.ST_SIZE] return content_size class HelloHandler(tornado.web.RequestHandler): def get(self): return self.finish("Hello Tornado") class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/download", DownloadHandler), (r".*?", HelloHandler), ] tornado.web.Application.__init__(self, handlers) if __name__ == "__main__": port = 8899 application = Application() http_server = tornado.httpserver.HTTPServer(application, xheaders=True) http_server.listen(port) print('Listen on http://localhost:{0}'.format(port)) tornado.ioloop.IOLoop.instance().start()
"/download"路由的Get方法調用時,將會進行一個文件下載操做,將同目錄下的a.zip文件切片下載爲a.data文件。web
下載過程當中,會空出一些時間間隙,讓tornado繼續處理其餘類型的請求。app
下載過程綜合了python和tornado對yield的應用。異步