大容量文件上传早已不是什么新鲜问题,在.net 2.0时代,HTML5也还没有问世,要实现这样的功能,要么是改web.config,要么是用flash,要么是用一些第三方控件,然而这些解决问题的方法要么很麻烦,比如改配置,要么不稳定,比如文件上G以后,上传要么死掉,要么卡住,通过设置web.config并不能很好的解决这些问题。

这是一个Html5统治浏览器的时代,在这个新的时代,这种问题已被简化并解决,我们可以利用Html5分片上传的技术,那么Plupload则是一个对此技术进行封装的前端脚本库,这个库的好处是可以自动检测浏览器是否支持html5技术,不支持再检测是否支持flash技术,甚至是sliverlight技术,如果支持,就使用检测到的技术。

那么这个库到哪里下载,怎么搭建呢,比较懒的童鞋还是用Install-Package Plupload搞定吧,一个命令搞定所有事

下面给出一个例子,使用自已定义的控件来使用Plupload (Plupload也有自己的界面可以用),如下

Plupload支持的功能这里就不细说了,什么批量上传,这里我没有用到,主要是感觉它支持的事件非常丰富,文件选取后的事件,文件上传中的事件(可获得文件的上传进度),文件上传成功的事件,文件上传失败的事件,等等

我的例子主要是上传一个单个文件,并显示上传的进度条(使用jQuery的一个进度条插件)

下面的例子主要是为文件上传交给 UploadCoursePackage.ashx 来处理


/******************************************************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/

plupload上传大文件的更多相关文章

  1. ASP.NET 使用 plupload 上传大文件时出现“blob”文件的Bug

    最近在一个ASP.NET 项目中使用了plupload来上传文件,结果几天后客户发邮件说上传的文件不对,说是文件无法打开 在进入系统进行查看后发现上传的文件竟然没有后缀,经过一番测试发现如果文件上传的 ...

  2. [Asp.net]Uploadify上传大文件,Http error 404 解决方案

    引言 之前使用Uploadify做了一个上传图片并预览的功能,今天在项目中,要使用该插件上传大文件.之前弄过上传图片的demo,就使用该demo进行测试.可以查看我的这篇文章:[Asp.net]Upl ...

  3. php 上传大文件配置upload_max_filesize和post_max_size选项

    php 上传大文件配置upload_max_filesize和post_max_size选项 (2014-04-29 14:42:11) 转载▼ 标签: php.ini upload _files[f ...

  4. PHP上传大文件 分割文件上传

    最近遇到这么个情况,需要将一些大的文件上传到服务器,我现在拥有的权限是只能在一个网页版的文件管理系统来进行操作,可以解压,可以压缩,当然也可以用它来在线编辑.php文件. 文件有40M左右,但是服务器 ...

  5. ASP.NET上传大文件的问题

    原文:http://www.cnblogs.com/wolf-sun/p/3657241.html?utm_source=tuicool&utm_medium=referral 引言 之前使用 ...

  6. php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项

    php 上传大文件主要涉及配置 upload_max_filesize 和post_max_size两个选项   今天在做上传的时候出现一个非常怪的问题,有时候表单提交可以获取到值,有时候就获取不到了 ...

  7. SWFUpload上传大文件(暂时用用,真正用的时候还是要改的)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. PHP上传大文件和处理大数据

    1. 上传大文件 /* 以1.5M/秒的速度写入文件,防止一次过写入文件过大导致服务器出错(chy/20150327) */ $is_large_file = false; if( strlen($x ...

  9. QQ上传大文件为什么这么快

    今天和同事在群里讨论“QQ上传大文件/QQ群发送大文件时,可以在极短的时间内完成”是如何做到的. 有时候我们通过QQ上传一个几百M的文件,竟然只用了几秒钟,从带宽上限制可以得出,实际上传文件是不可能的 ...

随机推荐

  1. P1462 通往奥格瑞玛的道路[最短路+二分+堆优化]

    题目来源:洛谷 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描 ...

  2. 《3+1团队》第七次作业:团队项目设计完善&编码

    项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 3+1团队 团队博客地址 https://home.cnblogs.com/u/3-1group ...

  3. 如何在C中传递二维数组作为参数?

    回答: 在C语言中,有很多方法可以将2d数组作为参数传递.在下面的部分中,我描述了将2d数组作为参数传递给函数的几种方法. 使用指针传递2d数组以在c中运行 多维数组的第一个元素是另一个数组,所以在这 ...

  4. rest_framework/api.html

    解决办法 在setting.py文件中添加 'rest_framework' 注册这个应用 INSTALLED_APPS = [ 'django.contrib.admin', 'django.con ...

  5. jquery模仿淘宝星星打分

    今天做论坛页面有星星评分功能,以下是代码.用的时候引入jquery <span> <ul class="hs_df_xx"> <li><i ...

  6. bzoj 4922: [Lydsy1706月赛]Karp-de-Chant Number 贪心+dp

    题意:给定 $n$ 个括号序,让你从中选取一些括号序按照任意顺序拼接,最终生成一个合法的括号序列,求这个合法序列长度最大值. 题解:假设括号序列相对顺序固定,而我们要做的只是判断选还是不选的话可以转化 ...

  7. Educational Codeforces Round 60 D. Magic Gems

    易得递推式为f[i]=f[i-1]+f[i-M] 最终答案即为f[N]. 由于N很大,用矩阵快速幂求解. code: #include<bits/stdc++.h> using names ...

  8. P1021 邮票面值设计——搜索+完全背包

    P1021 邮票面值设计 题目意思是你最多用n张邮票,你可以自己设定k种邮票的面值,每种邮票数量无穷,你最多能用这k种邮票在不超过n张的情况下,组合成的价值要求是从1开始连续的, 求最大能连续到多少: ...

  9. C++中的平方、开方、绝对值怎么计算

    #include <math.h> //平方 pow() ,);// 4的平方=16 //开方 ,0.5);// 4的平方根=2 );// 4的平方根=2 //整数绝对值 int c = ...

  10. BZOJ3262陌上花开

    三维偏序的模板. 当然各种树套树都可以搞,这里用CDQ分治弄一下. 首先利用排序使第一维有序,然后利用cdq函数开始执行类似归并排序的操作,由于左区间的第一维一定小于右区间的第一维,所以我们在归并过程 ...