一般的小文件设置max_buffer_size的大小既可以解决问题,但是有的时候服务器的内存空间不够,这个时候就要考虑流式加载文件,上传一部分接受一部分
直接上代码,我们采用流式上传需要注意,前端上传文件将文件流放到body,但是后端接受时需要掐头去尾去掉一些heard信息等,具体自己可以上传个TXT文件打印下数据流看下
from tornado.web import RequestHandler @tornado.web.stream_request_body ##装饰器,采用流式加载 classReceiveHandler(RequestHandler): def initialize(self): self.bytes_read = 0 self.meta = dict() self.receiver = self.get_receiver() def prepare(self): """If no stream_request_body""" ##todo 可以做些前期处理 def data_received(self, chunk): self.receiver(chunk) def get_receiver(self): index = 0 SEPARATE = b'\r\n' def receiver(chunk): nonlocal index if index == 0: index +=1 split_chunk = chunk.split(SEPARATE) self.meta['boundary'] = SEPARATE + split_chunk[0] + b'--' + SEPARATE self.meta['header'] = SEPARATE.join(split_chunk[0:3]) self.meta['header'] += SEPARATE *2 self.meta['filename'] = split_chunk[1].split(b'=')[-1].replace(b'"',b'').decode() chunk = chunk[len(self.meta['header']):] # Stream掐头流式加载会将body里面一些不是文件的东西提取出来,需要过滤 import os self.fp = open('xxxx', "wb")##保存文件, self.fp.write(chunk) else: self.fp.write(chunk) return receiver @tornado.gen.coroutine def post(self, *args, **kwargs): try: # Stream去尾 self.meta['content_length'] = int(self.request.headers.get('Content-Length')) - len(self.meta['header']) - len(self.meta['boundary']) self.fp.seek(self.meta['content_length'], 0) self.fp.truncate() self.fp.close() except Exception as e: #print(str(e)) self.set_status(400) self.finish() def on_finish(self): ##todo