zoukankan      html  css  js  c++  java
  • BootStrap Progressbar 实现大文件上传的进度条

    1.首先实现大文件上传,如果是几兆或者几十兆的文件就用基本的上传方式就可以了,但是如果是大文件上传的话最好是用分片上传的方式。我这里主要是使用在客户端进行分片读取到服务器段,然后保存,到了服务器段读取完了之后将分片数据进行组合。

    2.前端代码如下:

    <%@ 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({  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.当然了后台还需要一些异常处理或者断电续传的工作要做,待续。。。

  • 相关阅读:
    java中为什么notify()可能会导致死锁,而notifyAll()则不会
    java中wait()和sleep()的区别;notify()和notifyall()区别
    你不知道的Golang盲点汇总【持续更新】
    rsync性能终极优化【Optimize rsync performance】
    基于cephfs搭建高可用分布式存储并mount到本地
    检测代码潜在bug和质量之SonarQube
    玩透二叉树(Binary-Tree)及前序(先序)、中序、后序【递归和非递归】遍历
    好用到哭!8个技巧让Vim菜鸟变专家
    Golang fmt Printf 格式化参数手册/详解/说明
    淘宝滑动验证码研究
  • 原文地址:https://www.cnblogs.com/caishuhua226/p/4705243.html
Copyright © 2011-2022 走看看