分块上传大文件

上传大文件需要改动web.config文件
在Web.Config 文件中添加下列设置:
<configuration>
<system.web>
<httpRuntime maxRequestLength="4096" executionTimeout="120"/>
</system.web>
</configuration>
设置说明:
1. maxRequestLength 这个属性限制文件上传的大小,是以KB 为单位的,默认值为
4096KB,而最大上限为2097151KB,大约是2GB。
2. executionTimeout 属性则是限制文件上传的时间,以秒为单位,默认值为90 秒,如
果您考虑到所设计的Web 应用系统上传时间要超过90 秒可延长设定值。
前台:
<%@ Page Language= "C#" AutoEventWireup= "true"  CodeFile= "Default.aspx.cs" Inherits= "HttpModelApp._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns= "http://www.w3.org/1999/xhtml" >
<head runat= "server">
    <title>无标题页</title>
</head>
<body>
   <form id= "form1" runat= "server" encType= "multipart/form-data" method= "post">
    <div>
        <INPUT id= "firstFile" type= "file" name= "firstFile" runat= "server"><br />
         <asp:Button ID= "Button1" runat= "server" OnClick= "Button1_Click" Text= "上传" /><br />
        <asp:Label ID= "Label1" runat= "server"></asp:Label></div>
        </form>
</body>
</html>
后台:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using HttpModelApp;

namespace HttpModelApp
{
     public partial class _Default : System.Web.UI.Page
    {
void Page_Load() void Page_Load(object sender, EventArgs e)
        {

        }

void Button1_Click() void Button1_Click(object sender, EventArgs e)
        {
            //要保存的位置
             string strDesPath = "D://";
             string strFileName = this.firstFile.PostedFile.FileName;
            strFileName = strDesPath + strFileName.Substring(strFileName.LastIndexOf("//"));
            float  i = this.firstFile.PostedFile.ContentLength;
            this.firstFile.PostedFile.SaveAs(strFileName);
            this.Label1.Text = "文件保存到了:" + strFileName + "大小"+ i/1024000 + "m";
            
        }
    }
}
配置:
<?xml version= "1.0" encoding= "utf-8"?>

<configuration>
  
    <appSettings/>
    <connectionStrings/>
  
    <system.web>
        <!--  
            设置 compilation debug= "true" 将调试符号插入
            已编译的页面中。但由于这会  
            影响性能,因此只在开发过程中将此值  
            设置为 true
        -->
        <compilation debug= "true" />
        <!--
            通过 <authentication> 节可以配置 ASP.NET 使用的  
            安全身份验证模式,
            以标识传入的用户。  
        -->
        <authentication mode= "Windows" />
        <!--
            如果在执行请求的过程中出现未处理的错误,
            则通过 <customErrors> 节可以配置相应的处理步骤。具体说来,
            开发人员通过该节可以配置
            要显示的 html 错误页
            以代替错误堆栈跟踪。

        <customErrors mode= "RemoteOnly" defaultRedirect= "GenericErrorPage.htm">
            < error statusCode= "403" redirect= "NoAccess.htm" />
            < error statusCode= "404" redirect= "FileNotFound.htm" />
        </customErrors>
        -->
      <httpModules>
        <add name= "HttpUploadModule"
           type= "HttpModelApp.HttpUploadModule, HttpModelApp" />

      </httpModules>
      <httpRuntime maxRequestLength= "2000000"  executionTimeout= "300"    />
    </system.web>
</configuration>
类:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web;

using System.Reflection;

namespace HttpModelApp
{
    //实现IHttpModule接口
     public class HttpUploadModule : IHttpModule
    {
HttpUploadModule() HttpUploadModule()
        {

        }

void Init() void Init(HttpApplication application)
        {
            //订阅事件
            application.BeginRequest += new EventHandler(this.Application_BeginRequest);
        }

void Dispose() void Dispose()
        {
        }

void Application_BeginRequest() void Application_BeginRequest(Object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            HttpWorkerRequest request = GetWorkerRequest(app.Context);
            Encoding encoding = app.Context.Request.ContentEncoding;

            int bytesRead = 0;  // 已读数据大小
            int read;           // 当前读取的块的大小
            int count = 8192;   // 分块大小
            byte[] buffer;      // 保存所有上传的数据

             if (request != null)
            {
                // 返回 HTTP 请求正文已被读取的部分。
                byte[] tempBuff = request.GetPreloadedEntityBody(); //要上传的文件

                // 如果是附件上传
                 if (tempBuff != null && IsUploadRequest(app.Request))    //判断是不是附件上传
                {
                    // 获取上传大小
                    //  
                    long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
                    
                    buffer = new byte[length];
                    count = tempBuff.Length; // 分块大小

                    // 将已上传数据复制过去
                    //
                    Buffer.BlockCopy(tempBuff,  //源数据
                        0,                      //从0开始读
                        buffer,                 //目标容器
                        bytesRead,              //指定存储的开始位置
                        count);                 //要复制的字节数。  


                    // 开始记录已上传大小
                    bytesRead = tempBuff.Length;

                    // 循环分块读取,直到所有数据读取结束
                     while (request.IsClientConnected() &&!request.IsEntireEntityBodyIsPreloaded() && bytesRead < length)
                    {
                        // 如果最后一块大小小于分块大小,则重新分块
                         if (bytesRead + count > length)
                        {
                            count = (int)(length - bytesRead);
                            tempBuff = new byte[count];
                        }

                        // 分块读取
                        read = request.ReadEntityBody(tempBuff, count);

                        // 复制已读数据块
                        Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);

                        // 记录已上传大小
                        bytesRead += read;

                    }
                     if (  request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded()  )
                    {
                        // 传入已上传完的数据
                        InjectTextParts(request, buffer);
                    }
                }
            }
        }


        HttpWorkerRequest GetWorkerRequest(HttpContext context)
        {

            IServiceProvider provider = (IServiceProvider)HttpContext.Current;
            return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
        }

        /// <summary>
        /// 传入已上传完的数据
        /// </summary>
        /// <param name= "request"></param>
        /// <param name= "textParts"></param>
        void InjectTextParts(HttpWorkerRequest request, byte[] textParts)
        {
            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;

            Type type = request.GetType();

             while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
            {
                type = type.BaseType;
            }

             if (type != null)
            {
                type.GetField( "_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
                type.GetField( "_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
                type.GetField( "_preloadedContent", bindingFlags).SetValue(request, textParts);
                type.GetField( "_preloadedContentRead", bindingFlags).SetValue(request, true);
            }
        }

static bool StringStartsWithAnotherIgnoreCase() static bool StringStartsWithAnotherIgnoreCase( string s1, string s2)
        {
            return ( string.Compare(s1, 0, s2, 0, s2.Length, true, CultureInfo.InvariantCulture) == 0);
        }

        /// <summary>
        /// 是否为附件上传
        /// 判断的根据是ContentType中有无multipart/form-data
        /// </summary>
        /// <param name= "request"></param>
        /// <returns></returns>
        bool IsUploadRequest(HttpRequest request)
        {
            return StringStartsWithAnotherIgnoreCase(request.ContentType, "multipart/form-data");
        }
    }
}

附件下载:
   httpmodel.dll
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值