tornado 静态文件,tornado文档

  tornado 静态文件,tornado文档

  

  文件上传的服务端技术解析

  俗话说,爱有多深,恨就有多深。龙卷风服务器就是这样一个矛盾体,它的缺点和优点一样明显和强烈。有人认为文件上传是tornado的一大缺陷,tornado将用户上传的文件存储在内存3354中,这意味着如果多个用户同时上传文件,内存开销会急剧增加。然而,我认为它使许多事情变得更容易。比如你要处理用户上传的内容,你就不用再打开文件了,因为内容在内存里。此外,在tornado的异步机制下,我不确定多个用户可以同时上传文件。这是一个有趣的问题。

  好了,言归正传。假设文件上传形式如下:

  formid= form _ upload action=/demo/upload enctype= multipart/form-data method= post

  input type= file name= want _ to _ upload _ file _ 1 /br/

  input type= file name= want _ to _ upload _ file _ 2 /br/

  输入=提交值=上传/

  /form机制允许一次上载多个文件。这里有几个问题需要特别说明。

  在提交表单之前,您需要为表单指定action和method的属性值。如果是上传文件,还需要设置enctype="multipart/form-data "。这三个属性可以用html写,也可以在提交前由js赋值。

  文件浏览是文件类型的输入标签自带的功能,程序员无法在浏览器框架内操作本地文件。标签的name属性用于将它与其他文件区分开,不是文件名,也不是文件对象,也不是文件内容。

  上面的表单提交到/demo/upload(假设上传的第一个文件名是dqd.jpg,第二个文件名是intro.png)。请求的对象包含文件字典,所有上传文件的信息都包含在这个结构中。让我们来看看这个请求的真实面目。文件:

  defpost(self):

  print self . request . files . keys()#[u want _ to _ upload _ file _ 1 ,uwant_to_upload_file_2]

  打印类型(self . request . files[ want _ to _ upload _ file _ 1 ])#长度为1的列表

  meta _ file _ 1=self . request . files[ want _ to _ upload _ file _ 1 ][0]

  printmeta_file_1.keys()#[body , content_type , filename]

  Len (meta _ file _ 1 [body]) # 31492,文件长度

  print meta _ file _ 1[ content _ type ]# image/JPEG

  meta _ file _ 1[ filename ]# dqd.jpg有了这些材料,我们可以尽一切努力来满足客户的需求。比如不做任何处理,直接用原文件名保存在指定路径(假设保存在/static/image/wiki目录下):

  lass="brush:php;toolbar:false">PROJECT_PATH=os.path.split(os.path.realpath(__file__))[0]

  upload_path=os.path.join(PROJECT_PATH,'static','image','wiki')

  file_name=os.path.join(upload_path,meta_file_1['filename'])

  withopen(file_name,'wb')asfp:

  fp.write(meta_file_1['body'])很多时候,需要对用户上传的文件重命名(比如,用时间戳为文件名),但文件后缀名不变。

  

fn,ext=os.path.splitext(meta_file_1['filename'])

  fn='%d%s'%(time.time()*1000,ext)

  file_name=os.path.join(upload_path,fn)

如果需要对用户上传的文件类型做检查,请使用文件的content_type,而不是文件的扩展名,因为前者更规范。比如,JPEG类型的图片文件,其后缀名可能是.jpg.jpeg.JPG.JPEG中的一种,而前者只有“image/jpeg”一种表示法。

  关于文件的content_type,网上资料多如牛毛,请自行搜索。

  处理用户上传的图片文件时,除了限制文件大小,有时候还要做缩放处理,甚至一并生成缩略图,此时就需要将文件内容转成易于处理的图像对象,比如,pil的Image。

  

fromPILimportImage

  importStringIO

  pilImg=Image.open(StringIO.StringIO(meta_file_1['body']))

  printpilImg.size

至于如何缩放、如何保存为文件,请自行检索相关资料。

  基于Ajax技术实现的文件上传客户端

  假定上传文件的表单是这样的:

  

<formid="form_upload"action="/demo/upload"enctype="multipart/form-data"method="post">

  <inputtype="file"name="wiki_img"id="wiki_img"/><br/>

  <inputid="doUpload"type="button"value="上传"/>

  </form>

方法1:使用 ajaxfileupload.js

  

<scriptsrc="jquery.js"></script>

  <scriptsrc="ajaxfileupload.js"></script>

  <scripttype="text/javascript">

  $("#doUpload").click(function(){

  $.ajaxFileUpload({

  url:'/demo/upload',

  secureuri:false,

  fileElementId:'wiki_img',

  dataType:'json',

  success:function(data){

  alert(data);

  }

  });

  });

  </script>

方法2:仅依赖 jquery.js

  

<scriptsrc="jquery.js"></script>

  <scripttype="text/javascript">

  varformData=newFormData();

  formData.append("file",$("#wiki_img")[0].files[0]);

  formData.append("filename",$("#wiki_img").val());

  

  $.ajax({

  url:'/demo/upload',

  type:'POST',

  async:false,

  data:formData,

  processData:false,

  contentType:false,

  beforeSend:function(){

  $("#upload_tips").html("正在进行,请稍候");

  },

  success:function(data){

  alert(data);

  }

  });

  </script>

文件下载的服务端技术解析

  相对于上传,文件的下载就简单得多。只需要记住两点:开始前告诉浏览器要传输的文件类型,结束前对浏览器说拜拜。文件类型并不是固定的,需要根据文件的实际情况来选择。详情请自行检索。

  

defget(self):

  self.set_header('Content-Type','application/octet-stream')

  withopen(filename,'rb')asf:

  whileTrue:

  data=f.read(buf_size)

  ifnotdata:

  break

  self.write(data)

  self.finish()

配合seek命令,可以实现更复杂的下载请求,比如,断点续传、分块下载、ajax异步请求等。

  众多python培训视频,尽在盛行IT软件开发工作室,欢迎在线学习!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: