BootStrap Progressbar 實現大文件上傳的進度條

1.首先實現大文件上傳,若是是幾兆或者幾十兆的文件就用基本的上傳方式就能夠了,可是若是是大文件上傳的話最好是用分片上傳的方式。我這裏主要是使用在客戶端進行分片讀取到服務器段,而後保存,到了服務器段讀取完了以後將分片數據進行組合。css

2.前端代碼以下:html

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UploadTest2.aspx.cs" Inherits="Html5UploadTest.UploadTest2" %>

<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <title>HTML5大文件分片上傳示例</title>
    <script src="Scripts/jquery-1.8.2.js"></script>
    <link href="bootstrap-progressbar/bootstrap-progressbar-3.3.4.css" rel="stylesheet" />
    <script src="bootstrap-progressbar/bootstrap-progressbar.js"></script>

    <%--<link href="JqueryUI/jquery-ui.css" rel="stylesheet" />
    <script src="JqueryUI/jquery-ui.js"></script>--%>
    <script>
        function uploadFile() {
            $("#upload").attr("disabled", "disabled");
            var file = $("#file")[0].files[0],  //文件對象
                fileNum = $("#file")[0].files[0].length,
                name = file.name,        //文件名
                size = file.size,        //總大小
                succeed = 0;
            var shardSize = 2 * 1024 * 1024,    //以2MB爲一個分片
                shardCount = Math.ceil(size / shardSize);  //總片數
            $('.progress .progress-bar').attr('data-transitiongoal', 0).progressbar({ display_text: 'fill' });
            for (var i = 0; i < shardCount; ++i) {
                //計算每一片的起始與結束位置
                var start = i * shardSize,
                    end = Math.min(size, start + shardSize);
                //構造一個表單,FormData是HTML5新增的
                var form = new FormData();
                form.append("data", file.slice(start, end));  //slice方法用於切出文件的一部分
                form.append("name", name);
                form.append("total", shardCount);  //總片數
                form.append("index", i + 1);        //當前是第幾片
                //Ajax提交
                $.ajax({
                    url: "Upload.ashx",
                    type: "POST",
                    data: form,
                    async: true,        //異步
                    processData: false,  //很重要,告訴jquery不要對form進行處理
                    contentType: false,  //很重要,指定爲false才能造成正確的Content-Type
                    success: function () {
                        ++succeed;
                        $("#output").text(succeed + " / " + shardCount);
                        var percent = ((succeed / shardCount).toFixed(2)) * 100;
                        updateProgress(percent);
                        if (succeed == shardCount) {
                            $("#upload").removeAttr("disabled");
                        }
                    }
                });
            }
        }
        function progress(percent, $element) {
            var progressBarWidth = percent * $element.width() / 100;
            $element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");
        }
        
        //$(document).ready(function () {
        //    $('.progress .progress-bar').progressbar({ display_text: 'fill' });
        //});
        function updateProgress(percentage) {
            $('.progress .progress-bar').attr('data-transitiongoal', percentage).progressbar({ display_text: 'fill' });
        }
    </script>
</head>
<body>

    <input type="file" id="file" />

    <button id="upload" onclick="uploadFile();">上傳</button>

    <span id="output" style="font-size: 12px">等待</span>
    <div class="progress">
        <div id="progressBar" class="progress-bar" role="progressbar" data-transitiongoal=""></div>
    </div>
</body>

</html>
View Code

3. 後臺通常處理程序以下:前端

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

namespace Html5UploadTest
{
    /// <summary>
    /// Summary description for Upload
    /// </summary>
    public class Upload : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            try
            {
                //從Request中取參數,注意上傳的文件在Requst.Files中
                string name = context.Request["name"];
                int total = Convert.ToInt32(context.Request["total"]);
                int index = Convert.ToInt32(context.Request["index"]);
                var data = context.Request.Files["data"];
                //保存一個分片到磁盤上
                string dir = context.Request.MapPath("~/temp");
                string file = Path.Combine(dir, name + "_" + index);
                data.SaveAs(file);
                //若是已是最後一個分片,組合
                //固然你也能夠用其它方法好比接收每一個分片時直接寫到最終文件的相應位置上,但要控制好併發防止文件鎖衝突
                if (index == total)
                {
                    file = Path.Combine(dir, name);
                    //byte[] bytes = null;
                    using (FileStream fs = new FileStream(file, FileMode.OpenOrCreate))
                    {
                        for (int i = 1; i <= total; ++i)
                        {
                            string part = Path.Combine(dir, name + "_" + i);
                            //bytes = System.IO.File.ReadAllBytes(part);
                            //fs.Write(bytes, 0, bytes.Length);
                            //bytes = null;
                            System.IO.File.Delete(part);
                            fs.Close();
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            //返回是否成功,此處作了簡化處理
            //return Json(new { Error = 0 });
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
View Code

4.固然了後臺還須要一些異常處理或者斷電續傳的工做要作,待續。。。jquery

相關文章
相關標籤/搜索