zoukankan      html  css  js  c++  java
  • [导入]上传大文件时,找不到服务器的错误问题!

    利用RFC1867标准处理文件上传的两种方式:
    1.一次性得到上传的数据,然后分析处理。
    看了N多代码之后发现,目前无组件程序和一些COM组件都是使用Request.BinaryRead方法。一次性得到上传的数据,然后分析处理。这就是为什么上传大文件很慢的原因了,IIS超时不说,就算几百M文件上去了,分析处理也得一阵子。
    2.一边接收文件,一边写硬盘。

    了解了一下国外的商业组件,比较流行的有Power-Web,AspUpload,ActiveFile,ABCUpload,aspSmartUpload,SA-FileUp。其中比较优秀的是ASPUPLOAD和SA-FILE,他们号称可以处理2G的文件(SA-FILE EE版甚至没有文件大小的限制),而且效率也是非常棒,难道编程语言的效率差这么多?查了一些资料,觉得他们都是直接操作文件流。这样就不受文件大小的制约。但老外的东西也不是绝对完美,ASPUPLOAD处理大文件后,内存占用情况惊人。1G左右都是稀松平常。至于SA-FILE虽然是好东西但是破解难寻。然后发现2款.NET上传组件,Lion.Web.UpLoadModule和AspnetUpload也是操作文件流。但是上传速度和CPU占用率都不如老外的商业组件。
    做了个测试,LAN内传1G的文件。ASPUPLOAD上传速度平均是4.4M/s,CPU占用10-15,内存占用700M。SA-FILE也差不多这样。而AspnetUpload最快也只有1.5M/s,平均是700K/s,CPU占用15-39,测试环境: PIII800,256M内存,100M LAN。我想AspnetUpload速度慢是可能因为一边接收文件,一边写硬盘。资源占用低的代价就是降低传输速度。但也不得不佩服老外的程序,CPU占用如此之低.....

    三、ASP.NET上传文件遇到的问题
    我们在用ASP.NET上传大文件时都遇到过这样或那样的问题。设置很大的maxRequestLength值并不能完全解决问题,因为ASP.NET会block直到把整个文件载入内存后,再加以处理。实际上,如果文件很大的话,我们经常会见到Internet Explorer显示 "The page cannot be displayed - Cannot find server or DNS Error",好像是怎么也catch不了这个错误。为什么?因为这是个client side错误,server side端的Application_Error是处理不到的。
    四、ASP.NET大文件上传解决方案
    解决的方法是利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEntityBody方法从IIS为ASP.NET建立的pipe里分块读取数据。Chris Hynes为我们提供了这样的一个方案(用HttpModule),该方案除了允许你上传大文件外,还能实时显示上传进度。
    Lion.Web.UpLoadModule和AspnetUpload 两个.NET组件都是利用的这个方案。

    方案原理:
    利用HttpHandler实现了类似于ISAPI Extention的功能,处理请求(Request)的信息和发送响应(Response)。

    方案要点:
    1. httpHandler or HttpModule
    a.在asp.net进程处理request请求之前截获request对象
    b.分块读取和写入数据
    c.实时跟踪上传进度更新meta信息
    2. 利用隐含的HttpWorkerRequest用它的GetPreloadedEntityBody 和 ReadEntityBody方法处理文件流

    =====================================================================
    已经忘记上面的这段说明是从什么地方搜索到的了,它对ASP.net里的大文件上传说明的还是很清楚的。而我只想在这里说明一个问题,就是:

    实际上,如果文件很大的话,我们经常会见到Internet Explorer显示 "The page cannot be displayed - Cannot find server or DNS Error",好像是怎么也catch不了这个错误。为什么?因为这是个client side错误,server side端的Application_Error是处理不到的。

    我试了好多次,发现这个错误确实是在服务器端,这是我的证明:
    11/7/2005 11:07:13 AM aa8b180d-a91e-4734-938f-00c066b4993b:aa8b180d-a91e-4734-938f-00c066b4993b.doc
    11/7/2005 11:08:07 AM Start Upload.......
    11/7/2005 11:08:11 AM HttpModule error.....
    11/7/2005 11:09:31 AM Start Upload.......
    11/7/2005 11:09:44 AM HttpModule error.....
    11/7/2005 11:10:43 AM Start Upload.......
    11/7/2005 11:10:46 AM 55007:49152
    11/7/2005 11:10:46 AM -----------------------------7d531c2e1705ac
    其中的两次,都是因为我上传了大的文件,而使程序出现了错误。而这个错误不是用try和catch块来处理的,而是在
      private void WebbUpload_Error(object sender, EventArgs e)
      {
       #region function WebbUpload_Error
       WebbTextTrace.TraceMsg("HttpModule error.....");
       #endregion
       this.Dispose();
      }
    也就是说,当我们上传很大的文件的时候,服务器它会很快的检测文件的大小,然后返回错误。事实也证明,每次我都只能上传一半的文件。出现这个问题是怎么回事呢?

    如果我们没有自己写HttpModule,那么服务器有自己的处理模块,这个时候就是只能上传小文件,太大的文件服务器就会现出错误。
    而如果我们自己写了HttpModule之后就是不是一定不现出这个错误呢?不一定,我就在测试中遇到好几次这样的问题,原因是我在处理文件流时候,或者根本就不是ASP.net的HttpModul出现问题,而是出现一些没有办法捕获到的异常(.net里有很多),确切的说是我们的.net平台上的托管代码没办法捕获到的异常,而这个异常只能交给IIS的非托管模块去捕获了。所以最后返回的就是服务器没有找到的错误。

    因此,如果现出这样的错误,而且按照上面的办法写了自己的HttpModul模块还不能解决问题的,那就是说:你的模块里发生了.net不兼容的异常,而此异常导致了上面的错误。而出现.net无法捕获的异常,可以很肯定的说:一定是你的程序出现了问题。所以,这个时候注意,小心检测一下代码。。

    我出现了好几次错误,分别是出现在这些地方:
    1、一次字节循环读取错误。
    2、一次除0错误(这个应该是可以捕获到的吧,但没有,不知道为什么?)
    3、资源锁定错误。确切的说,我自己也记不清到底是什么错误,因为每次都只是一个服务器找不到的错误,之后只能通过手动的查找代码,发现问题,然后猜测。。。
    .net本身的异常机制里就有一些问题,特别是在托管兼容上。

    好了,希望这篇文章能帮助一些人。。。


     


    文章来源:http://computer.mblogger.cn/wucountry/posts/48676.aspx
    ================================
      /\_/\                        
     (=^o^=)  Wu.Country@侠缘      
     (~)@(~)  一辈子,用心做一件事!
    --------------------------------
      学而不思则罔,思而不学则怠!  
    ================================
  • 相关阅读:
    【leetcode】1020. Partition Array Into Three Parts With Equal Sum
    【leetcode】572. Subtree of Another Tree
    【leetcode】123. Best Time to Buy and Sell Stock III
    【leetcode】309. Best Time to Buy and Sell Stock with Cooldown
    【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
    【leetcode】467. Unique Substrings in Wraparound String
    【leetcode】823. Binary Trees With Factors
    【leetcode】143. Reorder List
    【leetcode】1014. Capacity To Ship Packages Within D Days
    【leetcode】1013. Pairs of Songs With Total Durations Divisible by 60
  • 原文地址:https://www.cnblogs.com/WuCountry/p/305651.html
Copyright © 2011-2022 走看看