plupload上傳大文件

大容量文件上傳早已不是什麼新鮮問題,在.net 2.0時代,HTML5也尚未問世,要實現這樣的功能,要麼是改web.config,要麼是用flash,要麼是用一些第三方控件,然而這些解決問題的方法要麼很麻煩,好比改配置,要麼不穩定,好比文件上G之後,上傳要麼死掉,要麼卡住,經過設置web.config並不能很好的解決這些問題。html

這是一個Html5統治瀏覽器的時代,在這個新的時代,這種問題已被簡化並解決,咱們能夠利用Html5分片上傳的技術,那麼Plupload則是一個對此技術進行封裝的前端腳本庫,這個庫的好處是能夠自動檢測瀏覽器是否支持html5技術,不支持再檢測是否支持flash技術,甚至是sliverlight技術,若是支持,就使用檢測到的技術。前端

那麼這個庫到哪裏下載,怎麼搭建呢,比較懶的童鞋仍是用Install-Package Plupload搞定吧,一個命令搞定全部事html5

下面給出一個例子,使用自已定義的控件來使用Plupload (Plupload也有本身的界面能夠用),以下jquery

這裏寫圖片描述

Plupload支持的功能這裏就不細說了,什麼批量上傳,這裏我沒有用到,主要是感受它支持的事件很是豐富,文件選取後的事件,文件上傳中的事件(可得到文件的上傳進度),文件上傳成功的事件,文件上傳失敗的事件,等等web

個人例子主要是上傳一個單個文件,並顯示上傳的進度條(使用jQuery的一個進度條插件)ajax

下面的例子主要是爲文件上傳交給 UploadCoursePackage.ashx 來處理json

  

            /******************************************************ProgressBar********************************************************/後端

            var progressBar = $("#loading").progressbar({ width: '500px', color: '#B3240E', border: '1px solid #000000' });瀏覽器

            /******************************************************Plupload***********************************************************/服務器

            //實例化一個plupload上傳對象

            var uploader = new plupload.Uploader({

                browse_button: 'browse', //觸發文件選擇對話框的按鈕,爲那個元素id

                runtimes: 'html5,flash,silverlight,html4',//兼容的上傳方式

                url: "Handlers/UploadCoursePackage.ashx", //後端交互處理地址

                max_retries: 3,     //容許重試次數

                chunk_size: '10mb', //分塊大小

                rename: true, //重命名

                dragdrop: false, //容許拖拽文件進行上傳

                unique_names: true, //文件名稱惟一性

 

                filters: { //過濾器

                    max_file_size: '999999999mb', //文件最大尺寸

                    mime_types: [ //容許上傳的文件類型

                        { title: "Zip", extensions: "zip" },

                        { title: "PE", extensions: "pe" }

                    ]

                },

                //自定義參數 (鍵值對形式) 此處能夠定義參數

                multipart_params: {

                    type: "misoft"

                },

                // FLASH的配置

                flash_swf_url: "../Scripts/plupload/Moxie.swf",

 

                // Silverligh的配置

                silverlight_xap_url: "../Scripts/plupload/Moxie.xap",

 

                multi_selection: false //true:ctrl多文件上傳, false 單文件上傳 

            });

 

            //在實例對象上調用init()方法進行初始化

            uploader.init();

 

            uploader.bind('FilesAdded', function (uploader, files) {

                $("#<%=fileSource.ClientID %>").val(files[0].name);

                $.ajax(

                {

                    type: 'post',

                    url: 'HardDiskSpace.aspx/GetHardDiskFreeSpace',

                    data: {},

                    dataType: 'json',

                    contentType: 'application/json;charset=utf-8',

                    success: function (result) {

                        //選擇文件之後檢測服務器剩餘磁盤空間是否夠用

                        if (files.length > 0) {

                            if (parseInt(files[0].size) > parseInt(result.d)) {

                                $('#error-msg').text("文件容量大於剩餘磁盤空間,請聯繫管理員!");

                            } else {

                                $('#error-msg').text("");

                            }

                        }

                    },

                    error: function(xhr, err, obj) {

                        $('#error-msg').text("檢測服務器剩餘磁盤空間失敗");

                    }

                });

            });

 

            uploader.bind('UploadProgress', function (uploader, file) {

                var percent = file.percent;

                progressBar.progress(percent);

            });

 

            uploader.bind('FileUploaded', function (up, file, callBack) {

                var data = $.parseJSON(callBack.response);

                if (data.statusCode === "1") {

                    $("#<%=hfPackagePath.ClientID %>").val(data.filePath);

                    var id = $("#<%=hfCourseID.ClientID %>").val();

                    __doPostBack("save", id);

                } else {

                    hideLoading();

                    $('#error-msg').text(data.message);

                }

            });

 

            uploader.bind('Error', function (up, err) {

                alert("文件上傳失敗,錯誤信息: " + err.message);

            });

後臺 UploadCoursePackage.ashx 的代碼也重要,主要是文件分片跟不分片的處理方式不同
  

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.IO;

 

namespace WebUI.Handlers

{

    /// <summary>

    /// UploadCoursePackage 的摘要說明

    /// </summary>

    public class UploadCoursePackage : IHttpHandler

    {

 

        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentType = "text/plain";

 

            int statuscode = 1;

            string message = string.Empty;

            string filepath = string.Empty;

 

            if (context.Request.Files.Count > 0)

            {

                try

                {

                    string resourceDirectoryName = System.Configuration.ConfigurationManager.AppSettings["resourceDirectory"];

                    string path = context.Server.MapPath("~/" + resourceDirectoryName);

                    if (!Directory.Exists(path))

                        Directory.CreateDirectory(path);

 

                    int chunk = context.Request.Params["chunk"] != null ? int.Parse(context.Request.Params["chunk"]) : 0; //獲取當前的塊ID,若是不是分塊上傳的。chunk則爲0

                    string fileName = context.Request.Params["name"]; //這裏寫的比較潦草。判斷文件名是否爲空。

                    string type = context.Request.Params["type"]; //在前面JS中不是定義了自定義參數multipart_params的值麼。其中有個值是type:"misoft",此處就能夠獲取到這個值了。獲取到的type="misoft";

 

                    string ext = Path.GetExtension(fileName);

                    //fileName = string.Format("{0}{1}", Guid.NewGuid().ToString(), ext);

                    filepath = resourceDirectoryName + "/" + fileName;

                    fileName = Path.Combine(path, fileName);

 

                    //對文件流進行存儲 須要注意的是 files目錄必須存在(此處能夠作個判斷) 根據上面的chunk來判斷是塊上傳仍是普通上傳 上傳方式不同 ,致使的保存方式也會不同

                    FileStream fs = new FileStream(fileName, chunk == 0 ? FileMode.OpenOrCreate : FileMode.Append);

                    //write our input stream to a buffer

                    Byte[] buffer = null;

                    if (context.Request.ContentType == "application/octet-stream" && context.Request.ContentLength > 0)

                    {

                        buffer = new Byte[context.Request.InputStream.Length];

                        context.Request.InputStream.Read(buffer, 0, buffer.Length);

                    }

                    else if (context.Request.ContentType.Contains("multipart/form-data") && context.Request.Files.Count > 0 && context.Request.Files[0].ContentLength > 0)

                    {

                        buffer = new Byte[context.Request.Files[0].InputStream.Length];

                        context.Request.Files[0].InputStream.Read(buffer, 0, buffer.Length);

                    }

 

                    //write the buffer to a file.

                    if (buffer != null)

                        fs.Write(buffer, 0, buffer.Length);

                    fs.Close();

 

                    statuscode = 1;

                    message = "上傳成功";

 

                }

                catch (Exception ex)

                {

                    statuscode = -1001;

                    message = "保存時發生錯誤,請確保文件有效且格式正確";

 

                    Util.LogHelper logger = new Util.LogHelper();

                    string path = context.Server.MapPath("~/Logs");

                    logger.WriteLog(ex.Message, path);

                }

            }

            else

            {

                statuscode = -404;

                message = "上傳失敗,未接收到資源文件";

            }

 

            string msg = "{\"statusCode\":\"" + statuscode + "\",\"message\":\"" + message + "\",\"filePath\":\"" + filepath + "\"}";

            context.Response.Write(msg);

        }

 

        public bool IsReusable

        {

            get

            {

                return false;

            }

        }

    }

}

再附送一個檢測服務器端硬盤剩餘空間的功能吧

using System; 
   
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace WebUI
{
    public partial class CheckHardDiskFreeSpace : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
 
        /// <summary>
        /// 獲取磁盤剩餘容量
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public static string GetHardDiskFreeSpace()
        {
            const string strHardDiskName = @"F:\";
 
            var freeSpace = string.Empty;
            var drives = DriveInfo.GetDrives();
            var myDrive = (from drive in drives
                where drive.Name == strHardDiskName
                select drive).FirstOrDefault();
            if (myDrive != null)
            {
                freeSpace = myDrive.TotalFreeSpace+""; 
            }
            return freeSpace;
        }
    }
}

 詳細配置信息能夠參考我寫的這篇文章:http://blog.ncmem.com/wordpress/2019/08/12/plupload%e4%b8%8a%e4%bc%a0%e5%a4%a7%e6%96%87%e4%bb%b6/

相關文章
相關標籤/搜索