大容量文件上传早已不是什么新鲜问题,在.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. 大数据之路week07--day01(HDFS学习,Java代码操作HDFS,将HDFS文件内容存入到Mysql)

    一.HDFS概述 数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,因此迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统 ...

  2. 13 复习 - webpack基本配置2

    在webpack下使用样式表 1.安装处理样式表的loader cnpm i style-loader css-loader -D //css cnpm i less-loader less -D / ...

  3. List集合和Set集合UML图总结

    1.List和Set,用RationalRose展示 2.Map

  4. vue computed、filters 用法笔记

    computed 在使用时的效果是属性,不是函数. 其次,computed 的值是“智能”响应的,依赖必须都是这个实例自己的东西,如果某个计算需要依赖传入的值,则推荐使用 methods. filte ...

  5. JZOJ 5870 地图

    直接解释题解,记录一下.

  6. Java链接Redis时出现 “ERR Client sent AUTH, but no password is set”

    Java链接Redis时出现 “ERR Client sent AUTH, but no password is set” 异常的原因及解决办法. [错误提示] redis.clients.jedis ...

  7. Linux ntp 时间同步服务配置

    一.基础环境 1.操作系统:CentOS 7.3 2.ntp:4.2.6 3.机器,服务端(192.168.1.210)客户端(192.168.1.211) 二.安装ntp yum -y instal ...

  8. Oracle 全部后台进程简介

    LGWR,DBWR,SMON,PMON,CKPT是必需的五个后台进程.ARCH是最重要的可选后台进程.最重要的六个进程:1.LGWR重做日志写进程,LOG write 负责将重做日志缓冲区记录顺序写入 ...

  9. 04_Logstash安装

    Logstash部署 1.部署JDK环境 2.下载Logstash源码包 $ wget https://artifacts.elastic.co/downloads/logstash/logstash ...

  10. CNN模型合集 | 1 LeNet

    1.1 LeNet的设计思想 1998年LeCun提出,经典结构,3层,五脏俱全(卷积层.Pooling层.FC网络.Sigmod层),对标传统神经网络.主要设计贡献 局部感受野(local rece ...