ASP.NET学习社区ASP.NET下载区ASP.NET源码 asp.net 上传大文件,显示进度条源码

1  /  2  页   12 跳转 查看:5038

asp.net 上传大文件,显示进度条源码

asp.net 上传大文件,显示进度条源码

这次在项目中,用到了大文件上传,要上传的文件有100多m,于是研究现在国内使用的大文件上传的
组件发现用的比较多的有两个控件AspnetUpload 2.0和Lion.Web.UpLoadModule,另外还有思归在它的博客
堂中所说的办法 http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx
  两个控件的方法是:利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEntityBody方法从IIS为ASP.NET建立的pipe里分块读取数据。Chris Hynes为我们提供了这样的一个方案(用HttpModule),该方案除了允许你上传大文件外,还能实时显示上传进度。
    Lion.Web.UpLoadModule和AspnetUpload 两个.NET组件都是利用的这个方案。
  当上传单文件时,两个软件的方法是一样的,继承HttpModule

  HttpApplication application1 = sender as HttpApplication;
  HttpWorkerRequest request1 = (HttpWorkerRequest) ((IServiceProvider) HttpContext.Current).GetService(typeof(HttpWorkerRequest));
  try
  {
    if (application1.Context.Request.ContentType.IndexOf("multipart/form-data") <= -1)
    {
    return;
    }
    //Check The HasEntityBody
    if (!request1.HasEntityBody())
    {
    return;
    }
    int num1 = 0;
    TimeSpan span1 = DateTime.Now.Subtract(this.beginTime);
    string text1 = application1.Context.Request.ContentType.ToLower();
    byte[] buffer1 = Encoding.ASCII.GetBytes(("\r\n--" + text1.Substring(text1.IndexOf("boundary=") + 9)).ToCharArray());
    int num2 = Convert.ToInt32(request1.GetKnownRequestHeader(11));
    Progress progress1 = new Progress();
    application1.Context.Items.Add("FileList", new Hashtable());
    byte[] buffer2 = request1.GetPreloadedEntityBody();
    num1 += buffer2.Length;
    string text2 = this.AnalysePreloadedEntityBody(buffer2, "UploadGUID");
    if (text2 != string.Empty)
    {
    application1.Context.Items.Add("LionSky_UpLoadModule_UploadGUID", text2);
    }
    bool flag1 = true;
    if ((num2 > this.UpLoadFileLength()) && ((0 > span1.TotalHours) || (span1.TotalHours > 3)))
    {
    flag1 = false;
    }
    if ((0 > span1.TotalHours) || (span1.TotalHours > 3))
    {
    flag1 = false;
    }
    string text3 = this.AnalysePreloadedEntityBody(buffer2, "UploadFolder");
    ArrayList list1 = new ArrayList();
    RequestStream stream1 = new RequestStream(buffer2, buffer1, null, RequestStream.FileStatus.Close, RequestStream.ReadStatus.NoRead, text3, flag1, application1.Context, string.Empty);
    list1.AddRange(stream1.ReadBody);
    if (text2 != string.Empty)
    {
    progress1.FileLength = num2;
    progress1.ReceivedLength = num1;
    progress1.FileName = stream1.OriginalFileName;
    progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
    application1.Application["_UploadGUID_" + text2] = progress1;
    }
    if (!request1.IsEntireEntityBodyIsPreloaded())
    {
    byte[] buffer4;
    ArrayList list2;
    int num3 = 204800;
    byte[] buffer3 = new byte[num3];
    while ((num2 - num1) >= num3)
    {
      if (!application1.Context.Response.IsClientConnected)
      {
      this.ClearApplication(application1);
      }
      num3 = request1.ReadEntityBody(buffer3, buffer3.Length);
      num1 += num3;
      list2 = stream1.ContentBody;
      if (list2.Count > 0)
      {
      buffer4 = new byte[list2.Count + buffer3.Length];
      list2.CopyTo(buffer4, 0);
      buffer3.CopyTo(buffer4, list2.Count);
      stream1 = new RequestStream(buffer4, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
      }
      else
      {
      stream1 = new RequestStream(buffer3, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
      }
      list1.AddRange(stream1.ReadBody);
      if (text2 != string.Empty)
      {
      progress1.ReceivedLength = num1;
      progress1.FileName = stream1.OriginalFileName;
      progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
      application1.Application["_UploadGUID_" + text2] = progress1;
      }
    }
    buffer3 = new byte[num2 - num1];
    if (!application1.Context.Response.IsClientConnected && (stream1.FStatus == RequestStream.FileStatus.Open))
    {
      this.ClearApplication(application1);
    }
    num3 = request1.ReadEntityBody(buffer3, buffer3.Length);
    list2 = stream1.ContentBody;
    if (list2.Count > 0)
    {
      buffer4 = new byte[list2.Count + buffer3.Length];
      list2.CopyTo(buffer4, 0);
      buffer3.CopyTo(buffer4, list2.Count);
      stream1 = new RequestStream(buffer4, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
    }
    else
    {
      stream1 = new RequestStream(buffer3, buffer1, stream1.FileStream, stream1.FStatus, stream1.RStatus, text3, flag1, application1.Context, stream1.OriginalFileName);
    }
    list1.AddRange(stream1.ReadBody);
    if (text2 != string.Empty)
    {
      progress1.ReceivedLength = num1 + buffer3.Length;
      progress1.FileName = stream1.OriginalFileName;
      progress1.FileCount = ((Hashtable) application1.Context.Items["FileList"]).Count;
      if (flag1)
      {
      progress1.UploadStatus = Progress.UploadStatusEnum.Uploaded;
      }
      else
      {
      application1.Application.Remove("_UploadGUID_" + text2);
      }
    }
    }
    byte[] buffer5 = new byte[list1.Count];
    list1.CopyTo(buffer5);
    this.PopulateRequestData(request1, buffer5);
  }
  catch (Exception exception1)
  {
    this.ClearApplication(application1);
    throw exception1;
  }


而思归所说的方法使用Mime也能上传大文件,在以下地址下载
  http://krystalware.com/files/slickupload.zip
  不过觉得的思归的方法容易很多

相关文章:
让asp.net默认的上传组件支持进度条反映
http://blog.joycode.com/dotey/archive/2005/06/12/53557.aspx // 宝玉
http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx // 思归
http://www.cnblogs.com/bestcomy/archive/2004/06/09/14267.aspx // bestcomy
http://krystalware.com/wiki/default.aspx/KrystalWiki.UploadSpike1
http://www.blueidea.com/tech/program/2005/2997.asp //ftp
通过Web Services上传和下载文件
http://dotnet.aspx.cc/ShowDetail.aspx?id=6381BD5F-51F3-4339-4239-1328564A1B2A
上传组件是如何不受settimeout限制的?
http://www.ietf.org/rfc/rfc1867.txt?number=1867
下载
http://support.microsoft.com/default.aspx?scid=kb;en-us;812406&Product=aspnet

相关内容文件上传显示进度条

上传控件源代码下载:

附件附件:

您所在的用户组无法下载或查看附件

最后编辑aspx1 最后编辑于 2008-01-07 10:16:29
http://www.Aspx1.Com
请帮忙宣传Aspx1 , Aspx1是ASP.NET学习者的家园 , 适宜长期居住.
 

我对WebbUpload这个组件的一些修改并应用了ajax技术

今天又做了一次大的修改,做了一些优化,去了一些Bug

上传界面l

上传界面2

上传界面3

wolf800@163.com
qq:174523323

附件附件:

您所在的用户组无法下载或查看附件

 

ASP.net下大文件上传的解决方案及WebbUpload组件源码

WebbUpload上传组件

特性简介
可上传上小于1G的文件,可以配置Web.config文件来设定上传文件的大小。
完全基于.NET开发,无需任何客户端配置。
提供同步的上传进度条,显示实时上传进度信息。
不破坏页面逻辑,提供类似ASP.NET内置上传组件的使用方法。
不受 Server.ScriptTimeout(请求的超时设置) 影响,可配置服务器处理时间。

开发测试环境
操作系统:Windows XP Professional(en)
开发工具:Microsoft Visual Studio.NET 2003
WEB服务器:IIS 5.0 & .NET Framework 1.1
浏览器:Internet Explorer 6.0/
2005-12-28更新说明:
1、修改了多文件上传时文件列表项为空时的错误。
2、更新了进度条的文件名显示方法,只保留文件名,删除了路径。下载 http://www.cnblogs.com/Files/WuCountry/WebbUploadSample.rar

关于WebbUpload上传组件的开发请查看相关链接:http://computer.mblogger.cn/wucountry/posts/48947.aspx


2006-01-25 第二次更新:




下载:http://www.cnblogs.com/Files/WuCountry/WebbUploadSample.zip

说明:
1、修改了一下上传进度条。
2、添加了几个属性,并修改了一个类名,原来的WebbUploadHandler改为WebbUploadStatusHandler。
3、可以不破坏HttpinpuFile上传,只用在调用时调用方法:EnableWebbUpload(false);就可以使用原来的上传方法。默认是使用WebbUpload.
4、本次下载文件里有演示的完整源代码。

相信本次修改会会使该组件越来越稳定,而且在我的实际项目里一直在使用。


2006-02-17
公开全部源代码。

昨天同事给了我一个工具,可以把DLL文件逆向为工程项目。所以这个上传组件也就没有必须在保护源代码了。
本来考虑到ASPNetUpload的商业行为,还准备暂时不公开这个组件的源代码,但这已经没有意义了。
Webb.WAVE.Controls.WebbUpload控件全部源代码:

 附件: 您所在的用户组无法下载或查看附件
结合上面的演示实例,应该是一个很好的学习项目。




Wu.Country@侠缘
http://www.cnblogs.com/WuCountry/
最后编辑asp.net 最后编辑于 2008-01-07 10:00:33
 

WebbUpload2 测试版

新的WebbUpload2测试版:
上传过程:


上传完成,但文件正在COPY的时候。如果直接存放到指定目录,不另存文件,那么对于文件来说,可以省去很多时间(大概30秒)。


相关说明在下载文件内。
http://www.cnblogs.com/Files/WuCountry/WebbUploadSample2.zip

测试报告文件:
http://www.cnblogs.com/Files/WuCountry/Load%20test%20result.zip

下载文件说明:
1、只提供了WebbUpload2的测试版,即Debug版本。建议不应该在正式项目中使用这个测试版,因为本人在测试中遇到过很多问题,由于时间关系,还没来得及修改。本人会尽快修改一些BUG并尽快发布RELEASE版本。
2、免费组件。
3、请在使用该组件时注意:使用该组件过程中,不管什么原因造成的任何损失,由使用者自己负责,本人不负任何责任。

2006-07-06附上源码

说明:
1、添加源码:http://www.cnblogs.com/Files/WuCountry/Webb.WAVE.Controls.Upload2.zip
2、添加上传日志。
3、添加上传开始时间。
4,修改一个BUG,特殊情况下临时缓存数据没能正确的写入到Context时去。
5、修改临时内存数据流,使内存占用大大降低。
6、公开免费组件,不提供任何技术支持,不负责任何使用该组件所造成的损失。
7、算法及组件流程分析可以参考下面的文章:

  http://wucountry.cnblogs.com/archive/2005/10/12/305688.html
  http://wucountry.cnblogs.com/archive/2005/11/07/305653.html (要研究算法,请先参考本文)
  http://wucountry.cnblogs.com/archive/2005/11/07/305651.html
  http://wucountry.cnblogs.com/archive/2005/11/07/305651.html

所有内容仅供参考!

2006-09-22修改了源代码。一此前发现的一些BUG已经修改。

附件附件:

您所在的用户组无法下载或查看附件

 

ASP.net下大文件上传的几个问题讨论

我研究这个问题已经很长时间了,ASPUpload的组件以及其它几个组件都使用过,多多少少对这些组件的工作原理有些了解,对于其它一些问题的讨论也都遇到过。前几个星期开发的WebbUpload2.0经过一段时间的测试后,发现它完全是一个超级大BUG,所以放弃发布它了。(不想害人了。)

先收集一些网络上关于这个问题的一些内容:

http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx 
http://www.cnblogs.com/bestcomy/archive/2004/06/09/14267.aspx BestCompy的上传组件
http://www.cnblogs.com/lion.net/archive/2004/07/14/24294.aspx lion 的上传组件
http://www.voidland.com/blog/article.asp?id=22


一般情况下,用ASP,net上传大文件会遇到以下几个问题:
1、无法Catch的页面找不到错误,一般会是DNS错误,这里有一个小讨论。
http://koffer.cnblogs.com/archive/2005/04/21/142799.aspx

2、还会遇到这样的几个问题:
Action cancled,我在测试WebbUpload2.0的时候遇到多次,跟踪的LOG发现是用户取消了上传。然而这是不可能的,唯一的可能就是IIS自动取消了用户上传。

还有一个错误就是:The page cannot be displayed
这个错误我也遇到过N次。而且为此郁闷了好几天。

总结一下问题:
首先要明确,在网络环境不是很坏的情况下,我们是可以在ASP.net下上传超级大文件的。BestCompy的组件就是一个很好的例子,然而对于出现的问题,我们要明确原因,然后再来处理。
1、Action canceled问题,
出现这一问题其实只有一种情况,就是在实现HttpMoudule的时候,出现程序错误。这时候IIS直接返回Action canceled,而不再生成逻辑页面。我在调试程序的时候发现,不仅在HttpModule里出现错误时,页面直接Cancel掉,而且在它的子函数里出现任何错误都一样!
有一个解决方法可以显示的让页面报误,就是大块的Catch,把整个Module Catch住,然后抛出自己的异常,这样会在进度条显示页面上看到这个错误。(不知道为什么会是在进度条页面上)。而上传页面上只有一个action canceled错误,但在访问其它页面前,它会快速的显示一下自己定义的错误。
因此解决这一问题的唯一方法就是:确保你的上传模块不能有任何的错误,否则IIS就直接Cancel掉了。注意:是在传超级大文件时(>100MB)。其它的不与讨论。

还有个错误就是The page cannot be displayed,报DNS错误。这个错误我一直不知道为什么,后来跟踪IIS内存,发现上传过程中,消耗过大时,IIS的进程会消失一次!不用说,就在这消失的一瞬间,页面找不到了(很正常不是吗?)。在MSDN上找到了相关的说明:
http://support.microsoft.com/kb/893227
这给我们的程序设计出了个大难题,我的WebbUpload2.0失败之处就是内存占用太大了,在上传1G的文件时,内存直线上升,到300MB的时候,IIS就闪了一次,于是出现页面找不到。跟踪发现在算法只一味的追求速度,而没有管内存。这是一个失败的做法!也让自己清醒了一次。知道错误以后,就可以自己解决问题。

Wu.Country@侠缘
 

回复:asp.net 上传大文件,显示进度条源码

┌┬┐─┬┐
  │┌─┴╮
  ││ ││
  ││ ││
┌│╰ │┘
╰╯└─╯┘
 

回复:asp.net 上传大文件,显示进度条源码

回复:asp.net 上传大文件,显示进度条源码
 

回复:asp.net 上传大文件,显示进度条源码

dddddddddddd
 

回复:asp.net 上传大文件,显示进度条源码

ddddddddddddddddddddd
 

回复: asp.net 上传大文件,显示进度条源码

好东西,收藏
 
1  /  2  页   12 跳转

版权所有 ASP.NET学习门户 2.0.1214   Sitemap  

返顶部