EXTJS+ASP.NET上传文件带实时进度条代码

一,文件夹

二,upLoad.cs是继承IHttpModule的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;
using System.Reflection;
using System.Globalization;
using System.Web.Hosting;

/// <summary>
///upLoad 的摘要说明
/// </summary>
public class upLoad : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += new EventHandler(this.Application_BeginRequest);
    }


    #region 用户变量
    private Encoding eContentEncode;//HTTP上下文的编码
    private bool bReadDataFinished = true;//用于表示上一个文件是否读取完毕,是否可以开始新文件的读取
    private HttpApplication app;//HttpApplication 类的一个实例在其生存期内被用于处理多个请求
    private byte[] bboundary;//界限数组 如:“-----------------------------7d87d1cc0a88”
    private byte[] bendboundary;
    private byte[] brequest;//没有文件信息的HTTP请求上下文字节数组
    private byte[] temp;//临时字节数组,用来存放上一次截取的一部分字节
    // private int ufiFileInfo.strFileGuid;//子集数,用来给文件命名
    #endregion


    void Application_BeginRequest(object sender, EventArgs e)
    {
        app = sender as HttpApplication;
        if (app == null) return;
        string ContentType = app.Request.ContentType;//类型共两种1(默认是application/x-www-form-urlencoded)上传是(multipart/form-data)
        //判断是否为上传文件类型
        if (string.Compare(ContentType, 0, "multipart/form-data", 0, "multipart/form-data".Length, true) != 0) return;
        int iReadStepSize = 7600;//分块读取数据的大小
        int iContentLength = app.Request.ContentLength;//文件总长度(不包括HTTP请求头)
        //声明一个具体的当前HTTP请求实例
        IServiceProvider provider = (IServiceProvider)HttpContext.Current;
        HttpWorkerRequest request = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

        eContentEncode = app.Request.ContentEncoding;//获取请求编码类型

        byte[] bPreloadedEnitityBody = request.GetPreloadedEntityBody();//获取HTTP请求已经被读取的部分
        bboundary = GetMultipartBoundary(app.Request.ContentType);//获取分界的数组(包含分界前的换行符)
        bendboundary = GetEndBoundary(app.Request.ContentType);
        temp = null;
        brequest = null;
        //   ufiFileInfo.strFileGuid = 0;


        int iRead = request.GetPreloadedEntityBodyLength();//已经读取的字节数

        string filename = null;//文件重命名
        string sguid = GetUploadId(bPreloadedEnitityBody, eContentEncode);
        UploadFileInfo ufiFileInfo = (UploadFileInfo)HttpContext.Current.Cache[sguid];
        ufiFileInfo.iTotalBytes = iContentLength;
        int iLeave = iContentLength - iRead;//剩余未读取的字节数
        //将读取的数据写入缓冲区然后再写入文件 
        bool bGoOnGetFileFromThisByte = true;
        if (bReadDataFinished)//判断是否是第一次读取数据
        {
            //判断是否有文件数据头
            int iDataStart1 = 0, iDataStart2 = 0, iDataStart3 = 0, iEndStart = 0;
            //判断是否含有“filename=”字段
            byte[] b1 = eContentEncode.GetBytes("filename=");
            int iStartIndex = 0, iEndIndex = bPreloadedEnitityBody.Length - 1;
            while (iStartIndex <= iEndIndex)
            {
                int i = -1;//判断是否找到完全匹配
                iStartIndex = Array.IndexOf(bPreloadedEnitityBody, b1[0], iStartIndex + 1);

                //如果没有找到
                if (iStartIndex < 0)
                {
                    break;
                }
                for (int index = 1; index < b1.Length; index++)
                {//对剩余字节进行逐个匹配
                    if (iStartIndex + index > bPreloadedEnitityBody.Length - 1)
                    {//超出范围
                        break;
                    }
                    if (bPreloadedEnitityBody[iStartIndex + index] != b1[index])
                    {
                        //如果不匹配
                        break;
                    }
                    i = 0;
                }
                if (i == 0)
                {
                    iDataStart1 = iStartIndex + 9;
                    break;
                }
            }
            //获取\r\nContent-Type: text/plain
            byte[] b2 = eContentEncode.GetBytes("\r\n");
            iStartIndex = iDataStart1;
            while (iStartIndex <= iEndIndex)
            {
                int i = -1;
                iStartIndex = Array.IndexOf(bPreloadedEnitityBody, b2[0], iStartIndex);
                if (iStartIndex < 0)
                {
                    break;
                }
                for (int index = 1; index < b2.Length; index++)
                {//对剩余字节进行逐个匹配
                    if (iStartIndex + index > bPreloadedEnitityBody.Length - 1)
                    {//超出范围
                        break;
                    }
                    if (bPreloadedEnitityBody[iStartIndex + index] != b2[index])
                    {
                        //如果不匹配
                        break;
                    }
                    i = 0;
                }
                if (i == 0)
                {
                    iDataStart2 = iStartIndex + 2;
                    break;
                }
            }
            //获取文件开始处的位置

            iStartIndex = iDataStart2;
            while (iStartIndex <= iEndIndex)
            {
                int i = -1;
                iStartIndex = Array.IndexOf(bPreloadedEnitityBody, b2[0], iStartIndex);
                if (iStartIndex < 0)
                {
                    break;
                }
                for (int index = 1; index < b2.Length; index++)
                {//对剩余字节进行逐个匹配
                    if (iStartIndex + index > bPreloadedEnitityBody.Length - 1)
                    {//超出范围
                        break;
                    }
                    if (bPreloadedEnitityBody[iStartIndex + index] != b2[index])
                    {
                        //如果不匹配
                        break;
                    }
                    i = 0;
                }
                if (i == 0)
                {
                    iDataStart3 = iStartIndex + 4;//因为有两个换行所以加4
                    break;
                }
            }
            //获取文件重命名filename
            int iStartTxtname = 0, iEndTxtname = 0;
            iStartIndex = 0;
            //获取name=“txtname”在数据头中的位置
            byte[] txtname = eContentEncode.GetBytes("txtname\"");
            while (iStartIndex <= iEndIndex)
            {
                int i = -1;
                iStartIndex = Array.IndexOf(bPreloadedEnitityBody, txtname[0], iStartIndex + 1);
                if (iStartIndex < 0)
                {
                    break;
                }
                for (int index = 1; index < txtname.Length; index++)
                {
                    if (bPreloadedEnitityBody[iStartIndex + index] != txtname[index])
                    {
                        break;
                    }
                    i = 0;
                }
                if (i == 0)
                {
                    iStartTxtname = iStartIndex + txtname.Length + 4;//加4是因为有两个\r\n
                    break;
                }
            }

            while (iStartTxtname <= iEndIndex)
            {
                int i = -1;
                iStartIndex = Array.IndexOf(bPreloadedEnitityBody, b2[0], iStartTxtname + 1);
                if (iStartIndex < 0)
                {
                    break;
                }
                for (int index = 1; index < b2.Length; index++)
                {
                    if (bPreloadedEnitityBody[iStartIndex + index] != b2[index])
                    {
                        break;
                    }
                    i = 0;
                }
                if (i == 0)
                {
                    iEndTxtname = iStartIndex;
                    break;
                }
            }

            filename = eContentEncode.GetString(bPreloadedEnitityBody, iStartTxtname, iEndTxtname - iStartTxtname);
            ufiFileInfo.StrFileName = filename;
            //开始写文件

            ufiFileInfo.IFileStart = iDataStart3;
            //获取后缀名
            ufiFileInfo.strExtensionName = GetExtensionName(bPreloadedEnitityBody, 0, bPreloadedEnitityBody.Length - 1);
            FileStream fs;
            DirectoryInfo diTempFileDir = new DirectoryInfo(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//"));

            if (!diTempFileDir.Exists)
            {//说明是对新文件的第一次读取,先创建临时文件夹和文件
                Directory.CreateDirectory(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//"));
            }
            FileInfo fiFile = new FileInfo(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + filename + "." + ufiFileInfo.strExtensionName));

            if (!fiFile.Exists)
            {
                fs = File.Create(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + filename + "." + ufiFileInfo.strExtensionName));
            }
            else
            {
                fs = new FileStream(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + filename + "." + ufiFileInfo.strExtensionName), FileMode.Open, FileAccess.Write);
            }
            //或取文件结束分隔符
            iEndStart = GetIndexOfByte(bPreloadedEnitityBody, bboundary, ufiFileInfo.IFileStart, bPreloadedEnitityBody.Length - 1, 0);
            //如果没有找到,说明文件还没有结束
            if (iEndStart < 0)
            {//本次请求只有部分文件数据
                temp = new byte[bboundary.Length];
                Array.Copy(bPreloadedEnitityBody, bPreloadedEnitityBody.Length - bboundary.Length, temp, 0, bboundary.Length);//预留一部分数组防止分界标志位于两个数据块中
                fs.Write(bPreloadedEnitityBody, ufiFileInfo.IFileStart, bPreloadedEnitityBody.Length - bboundary.Length - ufiFileInfo.IFileStart);
                bReadDataFinished = false;
                bGoOnGetFileFromThisByte = false;//因为在本次数组中只读取了部分文件数据,所以说明本次数组已经完全读取完毕。
            }
            else
            {//本次请求包含完整的文件数据
                if (GetIndexOfByte(bPreloadedEnitityBody, bendboundary, iEndStart, bPreloadedEnitityBody.Length - 1, 0) > 0)//这里可以提高下查询性能,可以直接从最后几个字符查起
                {//说明请求数据已经全步读取完毕

                    bGoOnGetFileFromThisByte = false;
                }
                else
                {
                    bGoOnGetFileFromThisByte = true;
                }

            }
            fs.Flush();
            fs.Close();
            fs.Dispose();

            //保留一段临时数组(防止分割分隔符)
            if (bGoOnGetFileFromThisByte)
            {
                temp = new byte[bPreloadedEnitityBody.Length - iEndStart];
                Array.Copy(bPreloadedEnitityBody, iEndStart, temp, 0, bPreloadedEnitityBody.Length - iEndStart);
                bPreloadedEnitityBody = UnionByte(temp, null);
                temp = null;
            }
        }
        else
        {
            int iEndStart = 0;
            bPreloadedEnitityBody = UnionByte(bPreloadedEnitityBody, temp);

            FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + filename + "." + ufiFileInfo.strExtensionName), FileMode.Append, FileAccess.Write);
            iEndStart = GetIndexOfByte(bPreloadedEnitityBody, bboundary, ufiFileInfo.ICurrentIndex, bPreloadedEnitityBody.Length - 1, 0);
            if (iEndStart < 0)
            {//文件数据没有结束
                temp = new byte[bboundary.Length];
                Array.Copy(bPreloadedEnitityBody, bPreloadedEnitityBody.Length - bboundary.Length, temp, 0, bboundary.Length);//预留一部分数组防止分界标志位于两个数据块中
                fs.Write(bPreloadedEnitityBody, 0, bPreloadedEnitityBody.Length - bboundary.Length);
                bGoOnGetFileFromThisByte = false;
            }
            else
            {

                if (iEndStart > 0)
                {
                    if (GetIndexOfByte(bPreloadedEnitityBody, bendboundary, iEndStart, bPreloadedEnitityBody.Length - 1, 0) > 0)//这里可以提高下查询性能,可以直接从最后几个字符查起
                    {//说明请求数据已经全部读取完毕

                        bGoOnGetFileFromThisByte = false;
                    }
                    else
                    {
                        bGoOnGetFileFromThisByte = true;
                    }

                }
                bReadDataFinished = true;
            }
            fs.Flush();
            fs.Close();
            fs.Dispose();


            if (bGoOnGetFileFromThisByte)
            {
                temp = new byte[bPreloadedEnitityBody.Length - iEndStart];
                Array.Copy(bPreloadedEnitityBody, iEndStart, temp, 0, bPreloadedEnitityBody.Length - iEndStart);
                bPreloadedEnitityBody = UnionByte(temp, null);
                temp = null;
            }

        }
        byte[] bReadStepByte = new byte[iReadStepSize];
        ufiFileInfo.dtStartFileRecv = DateTime.Now;
        ufiFileInfo.iReadedBytes = iRead;
        if (!request.IsEntireEntityBodyIsPreloaded())
        {
            while (iLeave > iReadStepSize && request.IsClientConnected())
            {
                iRead = request.ReadEntityBody(bReadStepByte, iReadStepSize);//之前不能去请求其它的数据

                GetFile(bReadStepByte, ufiFileInfo);

                ufiFileInfo.iReadedBytes += iRead;
                iLeave -= iRead;
            }
            if (iLeave > 0 && request.IsClientConnected())
            {
                iRead = request.ReadEntityBody(bReadStepByte, iLeave);//最后还剩一部分,因为小于n,所以写在循环外
                byte[] bLastByte = new byte[iRead];
                for (int i = 0; i < iRead; i++)
                {
                    bLastByte[i] = bReadStepByte[i];
                }
                GetFile(bLastByte, ufiFileInfo);

                ufiFileInfo.iReadedBytes += iRead;
            }
        }
    }


    #region 从数据块中获取文件内容
    /// <summary>
    /// 从数据块中获取文件内容
    /// </summary>
    /// <param name="bFileByte">数据块</param>
    private void GetFile(byte[] bFileByte, UploadFileInfo ufiFileInfo)
    {
        bool bGoOnGetFileFromThisByte = true;//当一个新文件读取结束时为true。用以读取多个上传文件
        while (bGoOnGetFileFromThisByte)
        {
            try
            {
                if (bFileByte.Length < 1) return;
                if (bReadDataFinished)
                {//对一个新文件的第一次读取

                    if (temp != null)
                    {
                        bFileByte = UnionByte(bFileByte, temp);
                    }
                    #region 判断是否有文件数据头
                    int iDataStart = 0, iDataStart2 = 0, iDataStart3 = 0, iEndStart = 0;
                    iDataStart = GetIndexOfByte(bFileByte, eContentEncode.GetBytes("filename="), 0, bFileByte.Length - 1, 9);//获取"filename="后的位置
                    if (iDataStart < 0)
                    {
                        temp = new byte[bendboundary.Length];
                        Array.Copy(bFileByte, bFileByte.Length - temp.Length, temp, 0, temp.Length);//预留一部分数组防止"filename="位于两个数据块中

                        return;
                    }

                    iDataStart2 = GetIndexOfByte(bFileByte, eContentEncode.GetBytes("\r\n"), iDataStart, bFileByte.Length - 1, 2);//获取\r\nContent-Type: text/plain这句话的起始坐标,这之后有两个换言之行符,所以下句偏移4
                    if (iDataStart2 < 0)
                    {
                        temp = new byte[bFileByte.Length - iDataStart + 9];//大小应该为数据块的结束位置-filename的起始位置+1,这样方便获取文件名
                        Array.Copy(bFileByte, bFileByte.Length - temp.Length, temp, 0, temp.Length);//预留一部分数组防止文件名位于两个数据块中 

                        return;
                    }
                    ufiFileInfo.strExtensionName = GetExtensionName(bFileByte, 0, bFileByte.Length - 1);
                    iDataStart3 = GetIndexOfByte(bFileByte, eContentEncode.GetBytes("\r\n"), iDataStart2, bFileByte.Length - 1, 4);//获取文件开始处的位置
                    if (iDataStart3 < 0)
                    {

                        temp = new byte[bFileByte.Length - iDataStart + 9];//大小应该为数据块的结束位置-filename的起始位置+1,这样方便获取文件名
                        Array.Copy(bFileByte, bFileByte.Length - temp.Length, temp, 0, temp.Length);//预留一部分数组防止文件名后的"Content-Type....\r\n"位于两个数据块中

                        return;
                    }
                    #endregion


                    ufiFileInfo.IFileStart = iDataStart3;
                    FileStream fs;
                    try
                    {
                        DirectoryInfo diTempFileDir = new DirectoryInfo(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//"));

                        if (!diTempFileDir.Exists)
                        {//说明是对新文件的第一次读取,先创建临时文件夹和文件
                            Directory.CreateDirectory(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//"));
                        }
                        FileInfo fiFile = new FileInfo(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + ufiFileInfo.StrFileName + "." + ufiFileInfo.strExtensionName));

                        if (!fiFile.Exists)
                        {
                            fs = File.Create(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + ufiFileInfo.StrFileName + "." + ufiFileInfo.strExtensionName));
                        }
                        else
                        {
                            fs = new FileStream(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + ufiFileInfo.StrFileName + "." + ufiFileInfo.strExtensionName), FileMode.Open, FileAccess.Write);
                        }
                        iEndStart = GetIndexOfByte(bFileByte, bboundary, ufiFileInfo.IFileStart, bFileByte.Length - 1, 0);
                        if (iEndStart < 0)
                        {//本次请求只有部分文件数据
                            temp = new byte[bboundary.Length];
                            Array.Copy(bFileByte, bFileByte.Length - bboundary.Length, temp, 0, bboundary.Length);//预留一部分数组防止分界标志位于两个数据块中
                            fs.Write(bFileByte, ufiFileInfo.IFileStart, bFileByte.Length - bboundary.Length - ufiFileInfo.IFileStart);
                            bReadDataFinished = false;
                            bGoOnGetFileFromThisByte = false;//因为在本次数组中只读取了部分文件数据,所以说明本次数组已经完全读取完毕。
                        }
                        else
                        {//本次请求包含完整的文件数据
                            if (GetIndexOfByte(bFileByte, bendboundary, iEndStart, bFileByte.Length - 1, 0) > 0)//这里可以提高下查询性能,可以直接从最后几个字符查起
                            {//说明请求数据已经全步读取完毕
                                // WriteHttpRequestWithoutFileData(bFileByte, iEndStart, bFileByte.Length - iEndStart, ref brequest);
                                bGoOnGetFileFromThisByte = false;
                            }
                            else
                            {
                                bGoOnGetFileFromThisByte = true;
                            }

                        }
                        fs.Flush();
                        fs.Close();
                        fs.Dispose();
                    }
                    catch
                    {
                        ufiFileInfo.Status = UploadStatus.Error;

                        return;//*****上传失败*****
                    }
                    if (bGoOnGetFileFromThisByte)
                    {
                        temp = new byte[bFileByte.Length - iEndStart];
                        Array.Copy(bFileByte, iEndStart, temp, 0, bFileByte.Length - iEndStart);
                        bFileByte = UnionByte(temp, null);
                        temp = null;
                    }
                }
                else
                {
                    int iEndStart = 0;
                    bFileByte = UnionByte(bFileByte, temp);
                    try
                    {
                        FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("TempUpload/" + ufiFileInfo.strFileGuid + "//" + ufiFileInfo.StrFileName + "." + ufiFileInfo.strExtensionName), FileMode.Append, FileAccess.Write);
                        iEndStart = GetIndexOfByte(bFileByte, bboundary, ufiFileInfo.ICurrentIndex, bFileByte.Length - 1, 0);
                        if (iEndStart < 0)
                        {//文件数据没有结束
                            temp = new byte[bboundary.Length];
                            Array.Copy(bFileByte, bFileByte.Length - bboundary.Length, temp, 0, bboundary.Length);//预留一部分数组防止分界标志位于两个数据块中
                            fs.Write(bFileByte, 0, bFileByte.Length - bboundary.Length);
                            bGoOnGetFileFromThisByte = false;
                        }
                        else
                        {

                            if (iEndStart > 0)
                            {
                                if (GetIndexOfByte(bFileByte, bendboundary, iEndStart, bFileByte.Length - 1, 0) > 0)//这里可以提高下查询性能,可以直接从最后几个字符查起
                                {//说明请求数据已经全部读取完毕

                                    bGoOnGetFileFromThisByte = false;
                                }
                                else
                                {
                                    bGoOnGetFileFromThisByte = true;
                                }

                            }
                            bReadDataFinished = true;
                        }
                        fs.Flush();
                        fs.Close();
                        fs.Dispose();
                    }
                    catch
                    {
                        ufiFileInfo.Status = UploadStatus.Error;

                        return;//*****上传失败*****
                    }
                    if (bGoOnGetFileFromThisByte)
                    {
                        temp = new byte[bFileByte.Length - iEndStart];
                        Array.Copy(bFileByte, iEndStart, temp, 0, bFileByte.Length - iEndStart);
                        bFileByte = UnionByte(temp, null);
                        temp = null;
                    }

                }
            }
            catch
            {
                ufiFileInfo.Status = UploadStatus.Error;

                return;//*****上传失败*****
            }
        }

    }

    #endregion

    #region 获取上传标识ID
    private string GetUploadId(byte[] array, Encoding eEncode)
    {
        byte[] b1 = eEncode.GetBytes("Content-Disposition: form-data; name=\"EUploadID\"");
        int iStartIndex = GetIndexOfByte(array, b1, 0, array.Length - 1, 0);
        if (iStartIndex < 0)
            return string.Empty;
        else
        {
            iStartIndex = GetIndexOfByte(array, eEncode.GetBytes("\r\n\r\n"), iStartIndex, array.Length - 1, 4);
            if (iStartIndex < 0)
                return string.Empty;
            else
            {
                int iEndIndex = GetIndexOfByte(array, eEncode.GetBytes("\r\n"), iStartIndex, array.Length - 1, 0);
                if (iEndIndex < 0) return string.Empty;
                else
                    return eEncode.GetString(array, iStartIndex, iEndIndex - iStartIndex);
            }
        }
    }
    #endregion

    #region 从数据块中读取文件扩展名
    /// <summary>
    /// 从数据块中读取文件扩展名
    /// </summary>
    /// <param name="array">数据块</param>
    /// <param name="istartindex">检索的起始位置</param>
    /// <param name="iendindex">检索的结束位置</param>
    /// <returns></returns>
    private string GetExtensionName(byte[] array, int istartindex, int iendindex)
    {
        byte[] b1 = eContentEncode.GetBytes("filename=");
        string strExtensionName;
        int iFileNameStartIndex = GetIndexOfByte(array, b1, istartindex, iendindex, b1.Length);//获取文件名的起始位置
        if (iFileNameStartIndex < 0)
        {//注:可能该字段刚好处于两个数据块中
            return string.Empty;
        }
        b1 = eContentEncode.GetBytes("\r\n");//"\r\n"占两个字节
        int iFileNameEndIndex = GetIndexOfByte(array, b1, iFileNameStartIndex, iendindex, 0) - 2;//获取文件名结尾的位置
        if (iFileNameEndIndex > iFileNameStartIndex)
        {//文件名格式是否正确直接在页面上处理,所以认为这里面的文件名合法
            strExtensionName = eContentEncode.GetString(array, iFileNameStartIndex + 1, iFileNameEndIndex - iFileNameStartIndex);//获取文件全名,包括了路径
        }
        else
        {
            return string.Empty;
        }
        return strExtensionName.Substring(strExtensionName.LastIndexOf(".") + 1);
    }
    #endregion

    #region 获取小数组在大数组中的位置
    /// <summary>
    /// 获取小数组在大数组中的位置
    /// </summary>
    /// <param name="b1">大数组</param>
    /// <param name="b2">小数组</param>
    /// <param name="iStartIndex">在大数组中检索的起始位置</param>
    /// <param name="iEndIndex">可在大数组中检索的最大的位置</param>
    /// <param name="iOffset">偏移量</param>
    /// <returns>检索到的位置和偏移量的和</returns>
    private int GetIndexOfByte(byte[] b1, byte[] b2, int iStartIndex, int iEndIndex, int iOffset)
    {
        int i = -1;//用来表示是否出错
        if (iStartIndex < 0 || iEndIndex < 0 || iStartIndex > iEndIndex) return -1;
        if (b2.Length == 1)
        {//如果小数组的长度就是1那表明查询一次就可以找到,不需要while
            return Array.IndexOf(b1, b2[0], iStartIndex);
        }
        while (iStartIndex <= iEndIndex)
        {//"="的情况是在b1只有一个字节的时候发生
            iStartIndex = Array.IndexOf(b1, b2[0], iStartIndex);//从b1中的iStartIndex位置处开始检索b2[0],没检索到则返回-1;
            if (iStartIndex < 0)
            {
                return -1;
            }
            for (int index = 1; index < b2.Length; index++)
            {//对剩余的字节进行逐个匹配
                if (iStartIndex + index > iEndIndex)
                {//如果索引的起点+预检索字符的长度>大数组的最大下标,则没有找到。
                    return -1;
                }
                if (b1[iStartIndex + index] != b2[index])
                {
                    i = -1;
                    iStartIndex++;
                    break;
                }
            }
            if (i >= 0)
            {//如果i>=0则说明找到完全匹配的
                i = iStartIndex;
                i += iOffset;
                break;
            }
            else
            {
                i = 0;
            }
        }
        return i;
    }
    #endregion

    #region 获取分隔符的字符数组
    /// <summary>
    /// 获取分隔符的字符数组
    /// </summary>
    /// <param name="ContentType">请求类型</param>
    /// <returns>分隔符字节数组</returns>
    private byte[] GetMultipartBoundary(string ContentType)
    {
        int nPos = ContentType.IndexOf("boundary=");
        string sTemp = ContentType.Substring(nPos + 9);

        string sBoundary = sTemp = "--" + sTemp;
        return Encoding.ASCII.GetBytes(("\r\n" + sTemp).ToCharArray());
    }

    /// <summary>
    /// 获取结束分隔符的字符数组
    /// </summary>
    /// <param name="ContentType">请求类型</param>
    /// <returns>分隔符字节数组</returns>
    private byte[] GetEndBoundary(string ContentType)
    {
        int nPos = ContentType.IndexOf("boundary=");
        string sTemp = ContentType.Substring(nPos + 9);

        string sBoundary = sTemp = "--" + sTemp + "--";
        return Encoding.ASCII.GetBytes(("\r\n" + sTemp).ToCharArray());
    }
    #endregion

    #region 拼合两个数组
    private byte[] UnionByte(byte[] bnewbyte, byte[] boldbyte)
    {
        int iLen = 0;

        if (bnewbyte != null)
        {//要添加到原数组中的字节如果不为空
            if (boldbyte != null)
            {
                iLen = boldbyte.Length;
            }
            byte[] unionbyte = new byte[bnewbyte.Length + iLen];
            if (boldbyte != null)
            {
                boldbyte.CopyTo(unionbyte, 0);
            }
            bnewbyte.CopyTo(unionbyte, iLen);
            return unionbyte;
        }
        else
        {
            return boldbyte;
        }
    }
    #endregion



    public void Dispose()
    {

    }




    public upLoad()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }
}

三,UploadFileInfo类是为了储存进度数据:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

/// <summary>
///UploadFileInfo 的摘要说明
/// </summary>
public class UploadFileInfo
{
   
    /// <summary>
    /// 已经上传的字节数
    /// </summary>
    public int iReadedBytes = 0;
    /// <summary>
    /// 需传的字节总数
    /// </summary>
    public int iTotalBytes = 0;
    public double iTotalSeconds = 0;
    /// <summary>
    /// 文件开始接收的时间
    /// </summary>
    public DateTime dtStartFileRecv;
    private string strFullName;
    /// <summary>
    /// 文件名:包含文件的完整路径
    /// </summary>
    public string StrFullName
    {
        get
        {
            return strFullName;
        }
        set
        {
            strFullName = value;
        }
    }

    private string strFileName;
    /// <summary>
    /// 文件名
    /// </summary>
    public string StrFileName
    {
        get
        {
            return strFileName;
        }
        set
        {
            strFileName = value;
        }
    }
    private int iFileStart;
    /// <summary>
    /// 文件数据部分的起始索引
    /// </summary>
    public int IFileStart
    {
        get
        {
            return iFileStart;
        }
        set
        {
            iFileStart = value;
        }
    }
    /// <summary>
    /// 文件扩展名
    /// </summary>
    public string strExtensionName;
    private int iCurrentIndex;
    public int ICurrentIndex
    {
        get
        {
            return iCurrentIndex;
        }
        set
        {
            iCurrentIndex = value;
        }
    }

    /// <summary>
    /// 返回上传速度,单位K/S
    /// </summary>
    public double fSpeed
    {
        get
        {
            if (iReadedBytes <= 0)
            {
                return 0;
            }
            TimeSpan ts = DateTime.Now - dtStartFileRecv;
            if (ts.TotalSeconds > 0)
            {
                this.iTotalSeconds = ts.TotalSeconds;
                return double.Parse((iReadedBytes / 1024 / ts.TotalSeconds).ToString("0.0"));

            }
            else
            {
                return 0;
            }
        }
    }

    /// <summary>
    /// 读取文件上传的进度
    /// </summary>
    public int iPercent
    {
        get
        {
            if (iTotalBytes > 0)
                return Convert.ToInt32(Math.Floor((iReadedBytes / (double)iTotalBytes) * 100));
            else
                return 0;
        }

    }
    private string str_FileGuid = string.Empty;
    /// <summary>
    /// 文件的唯一标识
    /// </summary>
    public string strFileGuid
    {
        get
        {
            return str_FileGuid;
        }
        set
        {
            str_FileGuid = value;
        }
    }

    public bool bHasErrorInfo = false;
    /// <summary>
    /// 上传的状态
    /// </summary>
    public UploadStatus Status = UploadStatus.Initializing;

    private string str_TempDir;
    /// <summary>
    /// 文件的临时路径
    /// </summary>
    public string strTempDir
    {
        get
        {
            return str_TempDir;
        }
        set
        {
            str_TempDir = value;
        }
    }
    public UploadFileInfo()
    {
        //
        // TODO: 在此处添加构造函数逻辑
        //


    }
    public UploadFileInfo(string sFileName)
    {
        strFileName = sFileName;
    }
    public void SaveAs(string strSavePath)
    {
        if (!strSavePath.EndsWith("\\"))
        {
            strSavePath = strSavePath + "\\";
        }

        DirectoryInfo di = new DirectoryInfo(strTempDir);
        if (di.Exists)
        {
            try
            {
                Directory.CreateDirectory(strSavePath);
                foreach (FileInfo fi in di.GetFiles())
                {
                    fi.MoveTo(strSavePath + fi.Name);
                }
                Status = UploadStatus.Finish;
            }
            catch
            {
                Status = UploadStatus.Error;
            }
        }
        else
        {
            Status = UploadStatus.Error;
        }
    }

}

/// <summary>
/// 上传的状态
/// </summary>
public enum UploadStatus
{
    /// <summary>
    /// 上传过程中出现错误
    /// </summary>
    Error,
    /// <summary>
    /// 正在初始化
    /// </summary>
    Initializing,
    /// <summary>
    /// 正在上传
    /// </summary>
    Uploading,
    /// <summary>
    /// 文件已经成功上传
    /// </summary>
    Finish,
    /// <summary>
    /// 上传过程被用户取消
    /// </summary>
    CanceledByUser
}
View Code

四,EXTJS就是它需要用到的一些文件。版本是extjs4.2

五,TempUpload文件上传文件夹。

六,Progress.aspx与Progress.cs

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Progress.aspx.cs" Inherits="Progress" %>

<!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>
    <script type="text/javascript">
        function myRefresh(url) {            
            setTimeout(location.replace(url), 1000);                     
        }
       
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     
    </div>
    </form>
</body>
</html>
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

public partial class Progress : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        UploadFileInfo ufi = null;
        ufi = (UploadFileInfo)HttpContext.Current.Cache[Request["UploadID"]];
        string stratevent = Request.QueryString["event"];

        if (!IsPostBack)
        {

            if (stratevent == null)
            {
                if (ufi == null)
                {
                    return;
                }
                else
                {
                    StringBuilder script = new StringBuilder();
                    script.Append("<script>myRefresh('Progress.aspx?UploadID=" + ufi.strFileGuid + "&event=start');</script>");
                    ClientScript.RegisterClientScriptBlock(this.GetType(), "js", script.ToString());
                }

            }


        }
        if (stratevent != null)
        {
            if (stratevent.ToLower() == "start" && ufi != null)
            {

                Response.Write(ufi.iPercent);
                Response.Flush();
                Response.Close();
                if (ufi.iPercent == 100)
                {
                    ufi.iReadedBytes = 0;
                }
            }
        }
    }
}
View Code

七,upfileload.aspx与upfileload.cs

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="upfileload.aspx.cs" Inherits="upfileload" %>

<%if (Request.Params["upload"] != "true")
  { %>
<!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 id="Head1" runat="server">
    <title></title>
    <link href="extjs/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
    <script src="extjs/ext-all-debug.js" type="text/javascript"></script>
    <script src="extjs/locale/ext-lang-zh_CN.js" type="text/javascript"></script>
    <script type="text/javascript">


        Ext.onReady(function () {
            Ext.QuickTips.init();
            //            var msg = function (title, msg) {
            //                Ext.Msg.show({
            //                    title: title,
            //                    msg: msg,
            //                    minWidth: 200,
            //                    model: true
            //                });
            //            }

            var fp = Ext.create('Ext.form.Panel', {
                renderTo: document.getElementById("form1"),
                width: 500,
                frame: true,
                title: '图片上传',
                autoHeight: true,
                bodyStyle: 'padding: 10px 10px 0 10px;',
                labelWidth: 50,
                defaults: {
                    anchor: '95%',
                    allowBlank: false,
                    msgTarget: 'side'
                },
                items: [{
                    xtype: 'hiddenfield',
                    name: 'EUploadID',
                    id: 'EUploadID',
                    value: document.getElementById("UploadID").value
                },
                                {
                                    xtype: 'textfield',
                                    name: 'txtname',
                                    id: 'txtname',
                                    fieldLabel: 'Name'
                                },
                 {
                     xtype: 'filefield',
                     id: 'form-file',
                     emptyText: 'Select an image',
                     fieldLabel: 'Photo',
                     name: 'photo-path',
                     buttonText: '浏览'
                 }, {
                     xtype: 'progressbar',
                     id: 'pgb'
                 }],
                buttons: [{
                    text: 'Save',
                    handler: function () {
                        if (fp.getForm().isValid()) {
                            fp.getForm().submit({
                                type: 'POST',
                                url: 'upfileload.aspx?action=upload&upload=true',


                                success: function (fp, o) {

                                }
                            });
                            ;

                            var f = function (v) {

                                var i = v / 100;

                                Ext.getCmp("pgb").updateProgress(i, '进度:' + v + '/100');
                                if (v == 100) {
                                    Ext.getCmp("pgb").reset();   //复位进度条
                                    Ext.getCmp("pgb").updateText('完成');
                                }
                            }

                            var xmlhttp;
                            function loadXMLDoc(url) {
                                xmlhttp = null;
                                if (window.XMLHttpRequest) {// code for IE7, Firefox, Opera, etc.
                                    xmlhttp = new XMLHttpRequest();
                                }
                                else if (window.ActiveXObject) {// code for IE6, IE5
                                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                                }
                                if (xmlhttp != null) {
                                    xmlhttp.open("GET", url, true);
                                    xmlhttp.onreadystatechange = function () {
                                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                                            var temp = xmlhttp.responseText;

                                            f(temp);
                                            if (temp != 100) {

                                                loadXMLDoc("Progress.aspx?event=start&UploadID=" + document.getElementById("UploadID").value);
                                            }
                                            temp = 0;
                                        }
                                    }
                                    xmlhttp.send(null);
                                }
                                else {
                                    alert("Your browser does not support XMLHTTP.");
                                }
                            }
                            loadXMLDoc("Progress.aspx?event=start&UploadID=" + document.getElementById("UploadID").value);

                        }
                    }
                }, {
                    text: 'Reset',
                    handler: function () {
                        fp.getForm().reset();
                    }
                }]

            });

        });
      
    </script>
</head>
<body>
    <form id="form1" runat="server">
    </form>
    <div id="progress" style="display: none" runat="server">
    </div>
</body>
</html>
<%} %>
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class upfileload : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            UploadFileInfo ufi = new UploadFileInfo();
            ufi.strFileGuid = Guid.NewGuid().ToString();//还是换成guid比较好,因为有可能会产生同一时刻上传的动作
            //ScriptManager.RegisterHiddenField();
            ClientScript.RegisterHiddenField("UploadID", ufi.strFileGuid);
            HttpContext.Current.Cache.Add(ufi.strFileGuid, ufi, null, DateTime.Now.AddDays(10), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);

            progress.InnerHtml = "<iframe src='Progress.aspx?UploadID=" + ufi.strFileGuid + "' width='100%'  scrolling=no frameborder='0'></iframe>";

        }


    }
}
View Code

八,web.config

<?xml version="1.0"?>
<!--
  有关如何配置 ASP.NET 应用程序的详细信息,请访问
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <httpModules>
      <add name="MyUpLoad" type="upLoad"/>
    </httpModules>
    <httpRuntime maxRequestLength="8192" executionTimeout="300000"/>
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>
</configuration>
View Code

 

posted @ 2014-10-15 09:28  flying_fish  阅读(482)  评论(0编辑  收藏  举报