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

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

那么这个库到哪里下载,怎么搭建呢,比较懒的童鞋还是用Install-Package 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);

});

/******************************************************Plupload***********************************************************/

后台 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%e6%95%b4%e4%b8%aa%e6%96%87%e4%bb%b6%e5%a4%b9-2/

plupload上传整个文件夹相关推荐

  1. 弹性服务器怎么上传文件,上传哪个文件夹弹性云服务器

    上传哪个文件夹弹性云服务器 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 本节 ...

  2. 码云上传本地文件夹,码云只能上传20个文件的突破方法

    码云官方地址:https://gitee.com/ 很多人不知道码云上传本地文件夹怎么操作,或者如何突破码云只能上传20个文件限制的问题,今天就来说说这事的方法吧. 简介: 码云是媲美GitHub的代 ...

  3. web上传整个文件夹

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...

  4. ajax上传本地音频文件,使用ajax将音频blob上传到文件夹中

    我正在构建一个录音项目,我想通过blob将音频上传到文件夹(上传). 这是我迄今取得的成就: var url = URL.createObjectURL(blob); var li = documen ...

  5. 多文件上传,文件夹上传

    前言 当您需要上传多个文件时,您可能会发现自己需要一种方法来处理多个上传任务.在某些情况下,您可能需要一次性上传所有文件.在其他情况下,您可能希望对文件进行排队以便逐个上传. 在本文中,我将介绍如何使 ...

  6. Google云端硬盘初学者使用Colaboratory出现的问题——指定已上传的文件夹

    1.将所需文件上传至Google Drive(我的是keras-yolo3-master) 2.新建或上传ipnb文件,并用Colaboratory打开(我这里新建是"授权代码.ipynb& ...

  7. 码云上传文件夹_码云上传本地文件夹,码云只能上传20个文件的突破方法

    码云官方地址:https://gitee.com/ 很多人不知道码云上传本地文件夹怎么操作,或者如何突破码云只能上传20个文件限制的问题,今天就来说说这事的方法吧. 简介: 码云是媲美GitHub的代 ...

  8. linux 传文件夹,linux下上传下载文件夹的方法

    Linux下目录复制:本机->远程服务器 scp -r /home/shaoxiaohu/test1 zhidao@192.168.0.1:/home/test2 test1为源目录,test2 ...

  9. Dropzone单文件上传、多文件上传、文件夹上传,springmvc接收,上传至Minio的一系列问题

    0 前言 1.项目需要上传文件和大量的文件夹,页面只有一个input file标签会很丑,偶然间得知dropzone类库, 决定使用. 2. 项目后端采用springmvc接收,调用minio代码上传 ...

最新文章

  1. spring中的jdk动态代理(代码步骤)
  2. Think Bayes - 我所理解的贝叶斯定理
  3. WEB前端学习六 js什么是闭包
  4. C++this指针的用法
  5. linux回到桌面的命令符_三 基本的base shell 命令
  6. clipboardjs 基本使用方式之一
  7. 数据治理注意哪些问题
  8. python 遗传算法书籍推荐_遗传算法(1) - Python实现
  9. IB数学考试真题题型解析
  10. ios 配置了代理且使用 chls.pro/ssl 下载不了证书,无法弹出下载证书的提示
  11. 三方协议服务器不填,毕业生三方协议可以不填么
  12. keras yolo3 使用 CIOU Loss
  13. 【移动端】滑动验证致使整个屏幕都在动
  14. Win系统 - 如何找出预装Windows系统的密钥
  15. 2014校园招聘_百度2014校园招聘
  16. QMainWindow使用介绍
  17. 【生活·日常】一个与世隔绝的大学生如何补办身份证
  18. hohi装修一年后的总结(完整版)_给要装修的人
  19. lua语言学习之自定义wireshark插件来解析自定义协议
  20. Python 安装模块(自用)

热门文章

  1. 如何优雅的从OSM(OpenStreetMap)上获取一个城市的路网?
  2. mysql 日期格式化 yyyymmdd_mysql中格式化日期详解
  3. 使用python爬虫爬取法律条文,并存入MYSQL
  4. 月销超千万,新防晒时代「蕉下」如何成为爆款制造机?
  5. PHP是哪里的轴承商标,轴承属于商标哪个类别?-轴承商标注册-八戒知识产权
  6. linux 的sleep()、usleep()、nanosleep()函数
  7. java——数组排序(升序和降序排列)
  8. textarea 赋值的方法
  9. Lync UI suppression 设置
  10. 动态效果html wow,WOW.js ? 在页面滚动时展现动感的元素动画效果_html/css_WEB-ITnose...