zoukankan      html  css  js  c++  java
  • 几种上传文件组件的性能比较【转载】

    近两天来由于项目需要使用上传组件,于是我仔细分析了Cos和FileUpload的源代码,并对它们的性能进行了测试比较,使用2M、20M、45M、200M的上传大小测试三种组件所花费的时间(单位为ms)结果是:

    2M

     

    第1次

    第2次

    第3次

    第4次

    平均

    Cos

    297

    203

    234

    245

    245

    FileUpload

    281

    312

    281

    312

    297

    SmartUpload

    531

    594

    485

    532

    536

     

     

    20M

     

    第1次

    第2次

    第3次

    第4次

    平均

    Cos

    2562

    2109

    2719

    2172

    2391

    FileUpload

    4062

    4140

    5360

    3922

    4371

    SmartUpload

    3453

    3094

    3078

    3547

    3293

     

     

    45M

     

    第1次

    第2次

    第3次

    第4次

    平均

    Cos

    4860

    4844

    5125

    5171

    5000

    FileUpload

    9000

    8391

    10375

    10078

    9461

    SmartUpload

    8265

    9187

    8672

    8856

    8745

     

     

    200M

     

    第1次

    第2次

    第3次

    第4次

    平均

    Cos

    55813

    52282

    54796

    51187

    53520

    FileUpload

    76343

    68531

    80954

    79031

    76215

    SmartUpload

    内存堆栈溢出 

     

     

     

     


    从上述的表格对比中可以看出Cos始终保持着良好的性能。在上传量较小(容量<2M,这是最常出现的情况)时,Cos比FileUpload性能并没有好很多,但SmartUpload就已经开始显出弱势。

       随着容量的增大,FileUpload和SmartUpload的性能下降非常快,直到200M容量时,SmartUpload已经不堪重负崩溃了,而Cos此时的花费时间比FileUpload少了20多秒,不能不说在本次的评测中,Cos的性能位居第一。

    通过对三种流行的上传组件进行对比,我认为选用Cos是比较好的。在实际的项目中,可以把上传的文件放到文件夹,文件路径存于数据库中以便于管理。

       如果需要把文件上传到数据库也很简单,从Cos中已经得到了上传文件(java.io.File),其后的操作很平常所做的一样:  通过File得到inputStream,存到数据库的blob或Clob字段即可。

       对于使用Struts的项目,我觉得还是使用FileUpload比较好,因为Struts天生集成了FileUpload的功能,使用FileUpload会带来很多的便利。而如果想要开发独立的上传组件,则用Cos是最好的选择,可以在Cos的基础上封装一层,暴露给业务程序员的只是一些简单易用的API,而且可以给这些API加上自定义的javaDoc,这对于实际的开发和将来的扩展都是非常方便的。
       下面对FileUpload的上传机制作一些分析,基本上,上传一个文件的过程在FileUpload中可以分为三个部分:
       1.由客户端把要上传的文件生成request数据流,与服务器端建立连接
       2.在服务器端接收request流,将流缓存到内存或磁盘中(具体缓存到什么地方,将由DiskFileUpload的setSizeThreshold(int cacheMax)方法来决定,当文件大小<cacheMax时,文件将被缓存到内存,否则将被缓存到磁盘的临时文件)
       3.由服务器端的内存或是临时文件中把文件输出到指定的目录(这个目录才是指定的文件上传目录).
       

       上述的第一步由浏览器完成,不用过多理会,重点是第二和第三步。
       第二步时,由DiskFileUpload的parseRequest(...)方法(其实这个方法是继承于FileUploadBase类,真正起解析request流作用的类是FileUploadBase)解析request流。在parseRequest(...)方法中,新建了一个MultipartStream实例,由此实例的readBodyData()方法将上传文件的流读到FileItem实例中,FileItem实例根据设置好的cacheMax大小,引用一个内存中的数据流或是一个磁盘上的数据流,注意此时文件已经上传到了服务器,但仍然没有传到设定的上传目录。   
       第三步时,调用FileItem实例的write(File file)方法,将已经存在于内存或是磁盘上的上传文件流拷贝到设定好的上传目录,至此上传仍未结束,因为磁盘中很可能保存了上传文件的临时文件(当设定的cacheMax<文件大小时),如何删除这些临时文件?有两种方法:1.显示调用FileItem实例的delete()方法。2.不调用任何方法,当FileItem被垃圾回收时,由finalize()方法删除临时文件。
  • 相关阅读:
    构建安全的Xml Web Service系列之如何察看SoapMessage
    web2.0盈利模式
    Asp.Net ajax v1.0莫名出现"Sys未定义"的原因
    北京街头发生一幕~让人深思!!!
    算法函数:得到一个字符串中的最大长度的数字
    手把手教你如何扩展GridView之自动排序篇
    手把手教你如何扩展GridView之自带Excel和Word导出
    nhibernate学习之集合组合依赖
    递归算法学习系列一(分而治之策略)
    手把手教你如何扩展GridView之自带分页
  • 原文地址:https://www.cnblogs.com/exmyth/p/2822746.html
Copyright © 2011-2022 走看看