如何仅用Python实现流式数据传输,复刻NodeJS大文件流发送功能?
Django/Python 实现流式传输大文件方案
你给出的NodeJS代码核心是不将整个大文件加载进内存,分块读取后直接写入HTTP响应返回给客户端,Django和Python原生都有对应实现,逻辑完全匹配。
Django 实现版本
Django内置的StreamingHttpResponse就是专门处理流式响应的类,不需要额外依赖:
- 首先编写视图逻辑
from django.http import StreamingHttpResponse, HttpResponse import os def stream_big_file(request): file_path = './content/bigFile.txt' # 处理文件不存在的异常,对应NodeJS里的error事件处理 if not os.path.exists(file_path): return HttpResponse("File not found", status=404) # 定义文件迭代生成器,默认每次读取4096字节,可以按需调整块大小 def file_iterator(chunk_size=4096): with open(file_path, 'r', encoding='utf-8') as f: while chunk := f.read(chunk_size): yield chunk # 直接把生成器传给StreamingHttpResponse,自动边读边返回,对应NodeJS的pipe逻辑 response = StreamingHttpResponse(file_iterator()) # 如果需要触发浏览器下载可以加下面这行响应头 # response['Content-Disposition'] = 'attachment; filename="bigFile.txt"' return response
- 绑定路由到urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.stream_big_file), ]
启动服务时指定5000端口即可:python manage.py runserver 0.0.0.0:5000
原生Python最简实现(不依赖Django)
如果要和你给出的NodeJS代码一样直接启动原生HTTP服务,不需要框架依赖,可以用内置的http模块实现:
from http.server import BaseHTTPRequestHandler, HTTPServer import os class RequestHandler(BaseHTTPRequestHandler): def do_GET(self): file_path = './content/bigFile.txt' if not os.path.exists(file_path): self.send_response(404) self.end_headers() self.wfile.write(b'File not found') return self.send_response(200) self.send_header('Content-Type', 'text/plain; charset=utf-8') self.end_headers() # 分块读取写入响应 with open(file_path, 'r', encoding='utf-8') as f: while chunk := f.read(4096): self.wfile.write(chunk.encode('utf-8')) if __name__ == '__main__': server = HTTPServer(('0.0.0.0', 5000), RequestHandler) server.serve_forever()
注意事项
- 如果传输的是二进制文件(视频、压缩包等),把open的模式改为
rb即可,不需要编码转换 - 块大小可以根据实际场景调整,4096字节是通用的最优取值
- 两种实现都不会把整个文件加载到内存,大文件传输时内存占用始终维持在极低水平,和你NodeJS代码的效果完全一致
内容的提问来源于stack exchange,提问作者KHAN
相关产品推荐
相关产品推荐

