ASP.NET大文件断点上传

前端代码

<!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>
    <script language="javascript">
        //全选
        function CheckAll(e, itemname) {
            var aa = document.getElementsByName(itemname);
            if (aa == undefined) return;
            for (var i = 0; i < aa.length; i++) aa[i].checked = e.checked;
        }   
    </script>
    <script language="javascript">
        //判断复选框是否选中
        function delss() {
            var checkArray = document.getElementsByName("Item");
            var checkNum = 0;
            for (var i = 0; i < checkArray.length; i++) {
                if (checkArray[i].checked) { checkNum++; }
            }
            if (checkNum == 0) {
                alert('对不起,您还没有选择!');
                return false;
            }
            else {
                if (confirm("您确定要删除吗?")) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="Timer1_Tick">
    </asp:Timer>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
        <ContentTemplate>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="tick" />
        </Triggers>
    </asp:UpdatePanel>
    <asp:FileUpload ID="FileUpload1" runat="server" />
    <asp:Button ID="Button1" runat="server" Text="上传文件" OnClick="Button1_Click" />
    <table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#cccccc">
        <tr class="spgl_bg">
            <td width="6%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                <input name="chkall" value="1" type="checkbox" οnclick="CheckAll(this,'Item')" class="qx" />全选
            </td>
            <td width="6%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                编号
            </td>
            <td width="16%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                名称
            </td>
            <td width="52%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                上传文件地址
            </td>
            <td width="8%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                已上传
            </td>
            <td width="12%" height="22" align="center" valign="middle" bgcolor="#FFFFFF">
                操作
            </td>
        </tr>
        <asp:Repeater ID="rptList" runat="server">
            <ItemTemplate>
                <tr>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>">
                        <input name="Item" type="checkbox" value='<%# Eval("fid")%>' />
                    </td>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>">
                        <%# Container.ItemIndex + 1 %>
                    </td>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>"
                        class="gml">
                        <%# Eval("FileNameLocal")%>
                    </td>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>"
                        class="gml">
                        <%# Eval("FilePathLocal")%>
                    </td>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>"
                        class="gml">
                        <%# Eval("PostedPercent")%>
                    </td>
                    <td align="center" valign="middle" bgcolor="<%#(Container.ItemIndex%2==0)?"#FFFFFF":"#f2f2f2"%>">
                        <asp:LinkButton ID="lbTop" runat="server" Text='续传' CommandArgument='<%# Eval("fid") %>'
                            OnCommand="lbTop_Click"></asp:LinkButton>|
                        <asp:LinkButton ID="lbClose" Visible="false" runat="server" Text='停止' CommandArgument='<%# Eval("fid") %>'
                            OnCommand="lbClose_Click"></asp:LinkButton>
                        <asp:LinkButton ID="lbDel" runat="server" Text="删除" OnCommand="lbDel_Click" CommandArgument='<%# Eval("fid") %>'
                            OnClientClick="javascript:return confirm('您确定要删除吗?');"></asp:LinkButton>
                    </td>
                    <asp:HiddenField ID="hidOK" runat="server" Value='<%# Eval("Isok") %>' />
                </tr>
            </ItemTemplate>
        </asp:Repeater>
    </table>
    <asp:Button ID="btnAllDelete" runat="server" Text="批量删除" class="plsc" CommandName="delete"
        OnClientClick="return delss()" OnCommand="btnAllDelete_Command" />
    </form>
</body>
</html>

后端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Web.demoSql.db;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Threading;

namespace Web
{
    public partial class Index : System.Web.UI.Page
    {
        #region
        public long m_FileSize;		//文件总大小。
        long m_RangePos;		    //文件块起始位置
        public long RangePos
        {
            set { this.m_RangePos = value; }
        }
        //文件读写锁,防止多个用户同时上传相同文件时,出现创建文件的错误
        static ReaderWriterLock m_writeLock = new ReaderWriterLock();
        #endregion
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GetList();
            }
        }

        /// <summary>
        /// 上传事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            #region 获取上传文件的信息
            string md5Fisrt = GenerateCheckCode10();
            string uidFisrt = "0";
            string fileLengthFisrt = FileUpload1.PostedFile.ContentLength.ToString();
            string fileSizeFisrt = Math.Round(Convert.ToDouble(FileUpload1.PostedFile.ContentLength) / Convert.ToDouble(1024 * 1024), 2).ToString() + "MB";
            string pathLocalFisrt = FileUpload1.PostedFile.FileName;
            #endregion

            string FileType = FileUpload1.FileName.Substring(FileUpload1.FileName.LastIndexOf(".") + 1);
            if (FileUpload1.FileName == "" || Request.Files.Count < 0)
            {
                string msg = "请选择文件!";
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
            }
            else if (FileType.ToLower() != "rar")
            {
                string msg = "文件格式不正确!";
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
            
            }
            else
            {
                #region 向数据库插入上传文件信息
                HttpUploaderDB db = new HttpUploaderDB();
                xdb_files inf = new xdb_files();
                inf.FileNameLocal = Path.GetFileName(pathLocalFisrt);
                inf.FilePathLocal = pathLocalFisrt;
                inf.FileNameRemote = md5Fisrt + Path.GetExtension(pathLocalFisrt).ToLower();

                //数据库存在相同文件
                if (db.GetFileInfByMd5(md5Fisrt, ref inf))
                {
                    inf.FileNameLocal = Path.GetFileName(pathLocalFisrt);
                    inf.FilePathLocal = pathLocalFisrt;
                    inf.uid = int.Parse(uidFisrt);//将当前文件UID设置为当前用户UID
                    inf.IsDeleted = false;
                    inf.fid = db.Add(ref inf);
                }//数据库不存在相同文件
                else
                {
                    HttpUploaderCfg cfg = new HttpUploaderCfg();
                    cfg.CreateUploadPath();

                    inf.uid = int.Parse(uidFisrt);//将当前文件UID设置为当前用户UID
                    inf.FileSize = fileSizeFisrt;
                    inf.FileMD5 = md5Fisrt;
                    inf.FileLength = Convert.ToInt32(fileLengthFisrt);
                    inf.FilePathRemote = Path.Combine(cfg.GetUploadPath(), inf.FileNameRemote);
                    inf.FilePathRelative = Path.Combine(cfg.GetRelatPath(), inf.FileNameRemote);
                    inf.fid = db.Add(ref inf);
                    GetList();
                }
                #endregion

                #region 更新上传进度

                int num = 0;
                string struid = uidFisrt;
                string strfid = inf.fid.ToString();
                string strFileSize = fileLengthFisrt;
                string strRangePos = num.ToString();

                if (strFileSize.Length > 0
                    && struid.Length > 0
                    && strfid.Length > 0
                    && md5Fisrt.Length > 0
                    && strRangePos.Length > 0
                    && Request.Files.Count > 0)
                {
                    long fileSize = Convert.ToInt64(strFileSize);
                    long rangePos = Convert.ToInt64(strRangePos);
                    int uid = Convert.ToInt32(struid);
                    int fid = Convert.ToInt32(strfid);

                    //临时文件大小
                    HttpPostedFile file = Request.Files.Get(0);
                    long rangeSize = 131072;
                    long rangeSiHH = 131072;
                    xdb_files infModel = new xdb_files();

                    for (long i = 0; i <= Convert.ToInt32(file.InputStream.Length); )
                    {
                        if (db.GetFileInfByFid(fid, ref infModel))
                        {
                            //已上传大小 = 文件块索引 + 临时文件块大小
                            //long postedLength = rangePos + rangeSize;
                            long postedLength = i + rangeSize;
                            long nownum = i;
                            if (file.InputStream.Length < postedLength)
                            {
                                postedLength = file.InputStream.Length - nownum;
                                rangeSiHH = file.InputStream.Length - nownum;
                            }
                            //上传百分比 = 已上传大小 / 文件总大小
                            double per = ((double)postedLength / (double)fileSize) * 100;
                            decimal perd = Math.Round((decimal)per, 2);
                            string postedPercent = perd.ToString() + "%";

                            //保存文件块数据
                            FileResumer res = new FileResumer();
                            res.m_FileSize = fileSize;//根据客户端文件大小在服务端创建文件
                            res.RangePos = rangePos;

                            #region
                            m_writeLock.AcquireWriterLock(1000);
                            //文件不存在则创建
                            if (!File.Exists(infModel.FilePathRemote))
                            {
                                FileStream fs = File.OpenWrite(infModel.FilePathRemote);
                                BinaryWriter w = new BinaryWriter(fs);
                                for (long ii = 0; ii < infModel.FileLength; ++ii)
                                {
                                    w.Write((byte)0);
                                }
                                w.Close();
                                fs.Close();
                            }
                            m_writeLock.ReleaseWriterLock();

                            //上传的文件大小不为空
                            if (rangeSiHH > 0)
                            {
                                //文件已存在,写入数据
                                //可能会有多个线程同时写文件。
                                FileStream fs = new FileStream(infModel.FilePathRemote, FileMode.Open, FileAccess.Write, FileShare.Write);
                                fs.Seek(i, SeekOrigin.Begin);
                                byte[] ByteArray = new byte[rangeSiHH];
                                file.InputStream.Read(ByteArray, 0, (int)rangeSiHH);
                                fs.Write(ByteArray, 0, (int)rangeSiHH);
                                fs.Flush();
                                fs.Close();
                            }
                            #endregion

                            //更新文件进度
                            db.UpdateProgress(uid, fid, rangePos, postedLength, postedPercent);
                            i += rangeSize;
                        }
                    }
                }
                #endregion

                #region 上传完成
                db.UploadComplete(md5Fisrt);
                #endregion

                GetList();
            }
            
        }

        /// <summary>
        /// 续传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lbTop_Click(object sender, CommandEventArgs e)
        {
            int id = Convert.ToInt32(e.CommandArgument);
            HttpUploaderDB db = new HttpUploaderDB();
            #region 设置按钮状态
            foreach (RepeaterItem grv in rptList.Items)
            {
                LinkButton lb1 = (LinkButton)rptList.Items[grv.ItemIndex].FindControl("lbTop");//续传
                LinkButton lb2 = (LinkButton)rptList.Items[grv.ItemIndex].FindControl("lbClose");//停止

                lb1.Enabled = false;
                lb2.Enabled = false;
            }
            LinkButton t = (LinkButton)sender;
            RepeaterItem ri = (RepeaterItem)t.NamingContainer;
            LinkButton itemid = ((LinkButton)ri.FindControl("lbClose"));
            itemid.Enabled = true;
            #endregion

            #region 获取上传文件的信息
            string md5Fisrt = GenerateCheckCode10();
            string uidFisrt = "0";
            string fileLengthFisrt = FileUpload1.PostedFile.ContentLength.ToString();
            string fileSizeFisrt = Math.Round(Convert.ToDouble(FileUpload1.PostedFile.ContentLength) / Convert.ToDouble(1024 * 1024), 2).ToString() + "MB";
            string pathLocalFisrt = FileUpload1.PostedFile.FileName;

            xdb_files model = db.GetModelByID(id);
            md5Fisrt = model.FileMD5;
            string FileType = FileUpload1.FileName.Substring(FileUpload1.FileName.LastIndexOf(".") + 1);

            if (FileUpload1.FileName == "" || Request.Files.Count < 0)
            {
                string msg = "请选择文件!";
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
            }
            else if (pathLocalFisrt != model.FilePathLocal || fileLengthFisrt != Convert.ToString(model.FileLength))
            {
                string msg = "第一次上传文件与本次上传文件不符合!";
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
            }             
            else if (FileType.ToLower() != "rar")
            {
                string msg = "文件格式不正确!";
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
            }
            else 
            {
                #region 更新上传进度

                int num = 0;
                string struid = uidFisrt;
                string strfid = id.ToString();
                string strFileSize = fileLengthFisrt;
                string strRangePos = num.ToString();

                if (strFileSize.Length > 0
                    && struid.Length > 0
                    && strfid.Length > 0
                    && md5Fisrt.Length > 0
                    && strRangePos.Length > 0
                    && Request.Files.Count > 0)
                {
                    long fileSize = Convert.ToInt64(strFileSize);
                    long rangePos = Convert.ToInt64(strRangePos);
                    int uid = Convert.ToInt32(struid);
                    int fid = Convert.ToInt32(strfid);

                    //临时文件大小
                    HttpPostedFile file = Request.Files.Get(0);
                    long rangeSize = 131072;
                    long rangeSiHH = 131072;
                    xdb_files infModel = new xdb_files();

                    for (long i = model.FilePos; i <= Convert.ToInt32(file.InputStream.Length); )
                    {
                        if (db.GetFileInfByFid(fid, ref infModel))
                        {
                            //已上传大小 = 文件块索引 + 临时文件块大小
                            //long postedLength = rangePos + rangeSize;
                            long postedLength = i + rangeSize;
                            long nownum = i;
                            if (file.InputStream.Length < postedLength)
                            {
                                postedLength = file.InputStream.Length - nownum;
                                rangeSiHH = file.InputStream.Length - nownum;
                            }
                            //上传百分比 = 已上传大小 / 文件总大小
                            double per = ((double)postedLength / (double)fileSize) * 100;
                            decimal perd = Math.Round((decimal)per, 2);
                            string postedPercent = perd.ToString() + "%";

                            //保存文件块数据
                            FileResumer res = new FileResumer();
                            res.m_FileSize = fileSize;//根据客户端文件大小在服务端创建文件
                            res.RangePos = rangePos;

                            #region
                            m_writeLock.AcquireWriterLock(1000);
                            //文件不存在则创建
                            if (!File.Exists(infModel.FilePathRemote))
                            {
                                FileStream fs = File.OpenWrite(infModel.FilePathRemote);
                                BinaryWriter w = new BinaryWriter(fs);
                                for (long ii = 0; ii < infModel.FileLength; ++ii)
                                {
                                    w.Write((byte)0);
                                }
                                w.Close();
                                fs.Close();
                            }
                            m_writeLock.ReleaseWriterLock();

                            //上传的文件大小不为空
                            if (rangeSiHH > 0)
                            {
                                //文件已存在,写入数据
                                //可能会有多个线程同时写文件。
                                FileStream fs = new FileStream(infModel.FilePathRemote, FileMode.Open, FileAccess.Write, FileShare.Write);
                                fs.Seek(i, SeekOrigin.Begin);
                                byte[] ByteArray = new byte[rangeSiHH];
                                file.InputStream.Read(ByteArray, 0, (int)rangeSiHH);
                                fs.Write(ByteArray, 0, (int)rangeSiHH);
                                fs.Flush();
                                fs.Close();
                            }
                            #endregion

                            //更新文件进度
                            db.UpdateProgress(uid, fid, rangePos, postedLength, postedPercent);
                            i += rangeSize;
                        }
                    }
                }
                #endregion

                #region 上传完成
                db.UploadComplete(md5Fisrt);
                #endregion
                GetList();
            }
            #endregion
            EnabledStop();
        }

        /// <summary>
        ///  停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lbClose_Click(object sender, CommandEventArgs e)
        {
            EnabledStop();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lbDel_Click(object sender, CommandEventArgs e)
        {
            int id = Convert.ToInt32(e.CommandArgument);
            HttpUploaderDB db = new HttpUploaderDB();
            db.Del(id);

            GetList();
        }

        /// <summary>
        /// 批量删除事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnAllDelete_Command(object sender, CommandEventArgs e)
        {
            HttpUploaderDB db = new HttpUploaderDB();
            string ids = Request.Form["Item"];
            switch (e.CommandName)
            {
                case "delete":
                    BakDelete(ids);
                    break;
            }
            GetList();
        }
        /// <summary>
        /// 批量删除方法
        /// </summary>
        /// <param name="ids"></param>
        private void BakDelete(string ids)
        {
            HttpUploaderDB db = new HttpUploaderDB();
            string strapp = ids;
            string[] strtemp = strapp.Split(',');
            foreach (string strs in strtemp)
            {
                db.Del(Convert.ToInt32(strs.ToString()));
            }
        }  

        /// <summary>
        /// 获取数据列表
        /// </summary>
        public void GetList()
        {
            HttpUploaderDB db = new HttpUploaderDB();
            rptList.DataSource = db.GetList();
            rptList.DataBind();
            EnabledStop();
        }

        /// <summary>
        /// 禁用所有停止控件,启用所有续传控件
        /// </summary>
        public void EnabledStop()
        {
            foreach (RepeaterItem grv in rptList.Items)
            {
                LinkButton lb1 = (LinkButton)rptList.Items[grv.ItemIndex].FindControl("lbTop");//续传
                LinkButton lb2 = (LinkButton)rptList.Items[grv.ItemIndex].FindControl("lbClose");//停止
                HiddenField hidk = (HiddenField)rptList.Items[grv.ItemIndex].FindControl("hidOK");//上传是否完成
                if (hidk.Value.ToLower() == "true")
                {
                    lb1.Enabled = false;
                    lb2.Enabled = false;
                }
                else
                {
                    lb1.Enabled = true;
                    lb2.Enabled = false;
                }
            }
        }

        /// <summary>
        /// 刷新时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Timer1_Tick(object sender, EventArgs e)
        {
            Label1.Text = DateTime.Now.ToString();
            //GetList();
        }

        private string GenerateCheckCode10()
        {
            int number;
            char code;
            string checkCode = String.Empty;

            System.Random random = new Random();

            for (int i = 0; i < 10; i++)
            {
                number = random.Next();

                if (number % 2 == 0)
                    code = (char)('0' + (char)(number % 10));
                else
                    code = (char)('A' + (char)(number % 26));

                checkCode += code.ToString();
            }
            return checkCode;
        }
    }
}



评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值