zoukankan      html  css  js  c++  java
  • 利用HTTP上传不能超过2G的文件

    Code
    1 //实现IHttpModule接口
    2     public class HttpUploadModule : IHttpModule
    3     {
    4         public HttpUploadModule()
    5         {
    6
    7         }
    8
    9         public void Init(HttpApplication application)
    10         {
    11             //订阅事件
    12             application.BeginRequest += new EventHandler(this.Application_BeginRequest);
    13         }
    14
    15         public void Dispose()
    16         {
    17         }
    18
    19         private void Application_BeginRequest(Object sender, EventArgs e)
    20         {
    21             HttpApplication app = sender as HttpApplication;
    22             HttpWorkerRequest request = GetWorkerRequest(app.Context);
    23             Encoding encoding = app.Context.Request.ContentEncoding;
    24
    25             int bytesRead = 0; // 已读数据大小
    26             int read;           // 当前读取的块的大小
    27             int count = 8192;   // 分块大小
    28             byte[] buffer;       // 保存所有上传的数据
    29
    30             if (request != null)
    31             {
    32                 // 返回 HTTP 请求正文已被读取的部分。
    33                 byte[] tempBuff = request.GetPreloadedEntityBody(); //要上传的文件
    34
    35                 // 如果是附件上传
    36                 if (tempBuff != null && IsUploadRequest(app.Request))     //判断是不是附件上传
    37                 {
    38                     // 获取上传大小
    39                     //
    40                     long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
    41                    
    42                     buffer = new byte[length];
    43                     count = tempBuff.Length; // 分块大小
    44
    45                     // 将已上传数据复制过去
    46                     //
    47                     Buffer.BlockCopy(tempBuff, //源数据
    48                         0,                       //从0开始读
    49                         buffer,                 //目标容器
    50                         bytesRead,               //指定存储的开始位置
    51                         count);                 //要复制的字节数。
    52
    53
    54                     // 开始记录已上传大小
    55                     bytesRead = tempBuff.Length;
    56
    57                     // 循环分块读取,直到所有数据读取结束
    58                     while (request.IsClientConnected() &&!request.IsEntireEntityBodyIsPreloaded() && bytesRead < length)
    59                     {
    60                         // 如果最后一块大小小于分块大小,则重新分块
    61                         if (bytesRead + count > length)
    62                         {
    63                             count = (int)(length - bytesRead);
    64                             tempBuff = new byte[count];
    65                         }
    66
    67                         // 分块读取
    68                         read = request.ReadEntityBody(tempBuff, count);
    69
    70                         // 复制已读数据块
    71                         Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);
    72
    73                         // 记录已上传大小
    74                         bytesRead += read;
    75
    76                     }
    77                     if ( request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded() )
    78                     {
    79                         // 传入已上传完的数据
    80                         InjectTextParts(request, buffer);
    81                     }
    82                 }
    83             }
    84         }
    85
    86
    87         HttpWorkerRequest GetWorkerRequest(HttpContext context)
    88         {
    89
    90             IServiceProvider provider = (IServiceProvider)HttpContext.Current;
    91             return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
    92         }
    93
    94         /// <summary>
    95         /// 传入已上传完的数据
    96         /// </summary>
    97         /// <param name="request"></param>
    98         /// <param name="textParts"></param>
    99         void InjectTextParts(HttpWorkerRequest request, byte[] textParts)
    100         {
    101             BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
    102
    103             Type type = request.GetType();
    104
    105             while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
    106             {
    107                 type = type.BaseType;
    108             }
    109
    110             if (type != null)
    111             {
    112                 type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
    113                 type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
    114                 type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);
    115                 type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
    116             }
    117         }
    118
    119         private static bool StringStartsWithAnotherIgnoreCase(string s1, string s2)
    120         {
    121             return (string.Compare(s1, 0, s2, 0, s2.Length, true, CultureInfo.InvariantCulture) == 0);
    122         }
    123
    124         /// <summary>
    125         /// 是否为附件上传
    126         /// 判断的根据是ContentType中有无multipart/form-data
    127         /// </summary>
    128         /// <param name="request"></param>
    129         /// <returns></returns>
    130         bool IsUploadRequest(HttpRequest request)
    131         {
    132             return StringStartsWithAnotherIgnoreCase(request.ContentType, "multipart/form-data");
    133         }
    134     }
    3.用法
    (1)修改web.config
       1 <httpModules>
    2         <add name="HttpUploadModule"
    3             type="HttpModelApp.HttpUploadModule, HttpModelApp" />
    4
    5       </httpModules>
    6       <httpRuntime
    7         maxRequestLength="2000000"
    8         executionTimeout="300"
    9     /> (2)aspx
       1 <form id="form1" runat="server" encType="multipart/form-data" method="post">
    2     <div>
    3         <INPUT id="firstFile" type="file" name="firstFile" runat="server">

    4           <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="上传" />

    5         <asp:Label ID="Label1" runat="server"></asp:Label></div>
    6     </form> (3)aspx.cs
       1 protected void Button1_Click(object sender, EventArgs e)
    2         {
    3             //要保存的位置
    4             string strDesPath = "D:\\";
    5             string strFileName = this.firstFile.PostedFile.FileName;
    6             strFileName =strDesPath + strFileName.Substring(strFileName.LastIndexOf("\\"));
    7             //
    8             this.firstFile.PostedFile.SaveAs(strFileName);
    9             this.Label1.Text = "文件保存到了:" + strFileName;
    10         }
    4.大文件上传的限制
    虽然可以上传大文件,但是这个大小也是有限制的,不能超过2G的大小。

    还有啊,大家不要忘记了导入命名空间.
    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Web;
    using System.Reflection;
    web.config文件如下
    <?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>

  • 相关阅读:
    Codefroces 920F SUM and REPLACE(线段树)
    POJ 2155 Matrix (2维树状数组)
    POJ 3067 Japan (树状数组求逆序对)
    Codeforces 919D Substring (拓扑排序+树形dp)
    拓扑排序
    Codeforces 889F Letters Removing(二分 + 线段树 || 树状数组)
    线段树扫描线(2---算矩形的相交面积)
    线段树扫描线(1---算矩形的总面积)
    hdu 6168 Numbers
    Educational Codeforces Round 27 A B C
  • 原文地址:https://www.cnblogs.com/cxlings/p/2388171.html
Copyright © 2011-2022 走看看