如何流传输大文件

问题

如何流传输大文件?

方案

要流传输大文件,需要添加传输译码(Transfer-Encoding)区块头,这样才能一边下载一边显示。否则,浏览器将缓冲所有数据直到下载完毕才显示。

如果这样写:直接修改基础字符串(例中就是j),然后用 yield 返回--是没有效果的。如果要使用 yield,就要向对所有内容使用 yield。因为这个函式此时是一个生成器。(注:具体细节请查看 yield 文档,在此不做过多论述。)

例子

  1. # Simple streaming server demonstration
  2. # Uses time.sleep to emulate a large file read
  3. import web
  4. import time
  5. urls = (
  6. "/", "count_holder",
  7. "/(.*)", "count_down",
  8. )
  9. app = web.application(urls, globals())
  10. class count_down:
  11. def GET(self,count):
  12. # These headers make it work in browsers
  13. web.header('Content-type','text/html')
  14. # 再次提醒,只有使用 web.py 自带的 http server 的时候才需要添加
  15. # `Transfer-Encoding: chunked` 这个 http header。web.py 自带的
  16. # http server 不应该在生产环境中使用,请使用 Apache/Nginx 等
  17. # web 服务器。
  18. web.header('Transfer-Encoding','chunked')
  19. yield '<h2>Prepare for Launch!</h2>'
  20. j = '<li>Liftoff in %s...</li>'
  21. yield '<ul>'
  22. count = int(count)
  23. for i in range(count,0,-1):
  24. out = j % i
  25. time.sleep(1)
  26. yield out
  27. yield '</ul>'
  28. time.sleep(1)
  29. yield '<h1>Lift off</h1>'
  30. class count_holder:
  31. def GET(self):
  32. web.header('Content-type','text/html')
  33. web.header('Transfer-Encoding','chunked')
  34. boxes = 4
  35. delay = 3
  36. countdown = 10
  37. for i in range(boxes):
  38. output = '<iframe src="/%d" width="200" height="500"></iframe>' % (countdown - i)
  39. yield output
  40. time.sleep(delay)
  41. if __name__ == "__main__":
  42. app.run()