WebUploader组件实际介绍:

  1. 官网:http://fex.baidu.com/webuploader/doc/index.html
  2. 组件优势及优化总结:http://itindex.net/detail/49267-webuploader-%E6%96%87%E4%BB%B6-%E4%B8%8A%E4%BC%A0
  3. 组件暂停功能的问题:https://github.com/fex-team/webuploader/issues/488
  4. 断点续传问题:https://github.com/fex-team/webuploader/issues/142
  5. 具体思路可以先参考链接:http://www.sxrczx.com/pages/blog.kazaff.me/uxgb1423648892626.html

以下内容于你对上述组件有了大致了解的基础上,结合C#实现大文件的上传、断点续传、分块等功能,展开说明的:

设计思路:在每次文件上传前,获取该文件的MD5值作为该文件的唯一标识符,然后对该文件进行分块处理(此处每块设置5M大小,详见2),按块分发请求(此处设置为3个线程发请求,详见2)文件开始上传前触发,一个文件只会触发一次 uploadStart事件,该事件会验证之前该文件是否已上传部分,返回已上传部分的块数编号列表,然后在下一个事件before-send(在文件分片处理之后,上传之前会触发)判断哪些块数已存在,上传不存在的文件块,至此基本上传流程已完成。

    /// <summary>
/// 文件上传消息类
/// </summary>
public class UploaderResult
{
public UploaderResult()
{
this.IsOver = false;
this.Chunk = ;
this.Chunks = ;
this.FileExtist = false;
this.ChunkNum = new List<int>();
} /// <summary>
/// 文件名称、当上传完成时将返回最终的文件名
/// </summary>
public string Name { get; set; } /// <summary>
/// 文件是否全部上传完成
/// </summary>
public bool IsOver { get; set; } /// <summary>
/// 消息
/// </summary>
public string Message { get; set; } /// <summary>
/// 如果为分块上传、返回当前的分块索引
/// </summary>
public int Chunk { get; set; } /// <summary>
/// 总的分块大小
/// </summary>
public int Chunks { get; set; } /// <summary>
/// 文件的MD5码
/// </summary>
public string Md5 { get; set; } /// <summary>
/// 上传的文件是否已经存在于服务器
/// </summary>
public bool FileExtist { get; set; } /// <summary>
/// 服务器已经存在的区块序号
/// </summary>
public List<int> ChunkNum { get; set; } /// <summary>
/// 文件扩展名
/// </summary>
public string FileExtension { get; set; } /// <summary>
/// 文件路径
/// </summary>
public string FilePath { get; set; } /// <summary>
/// 文件大小
/// </summary>
public int FileSize { get; set; }
}
        /// <summary>
/// 断点续传检测、MD5检测 秒传亦可以在这个方法块中实现,看需求
/// </summary>
public static UploaderResult ProcessCheck(HttpRequestBase request, string savepath = null
, Func<HttpPostedFileBase, string> setfilename = null, Func<string, bool> md5check = null)
{
UploaderResult obj = new UploaderResult();
string tempFilePath = savepath + "temp\\" + request["md5"] + "\\"; //文件大小
long size = request.Form["size"] == null ? : Convert.ToInt64(request.Form["size"]); //文件分块大小
long chunksize = request.Form["chunksize"] == null ? : Convert.ToInt64(request.Form["chunksize"]); //文件区块总数
int chunks = chunksize != ? Convert.ToInt32(size / chunksize) : ;
int j = ;
for (int i = ; i <= chunks; i++)
{
if (File.Exists(tempFilePath + i.ToString()))
{
obj.ChunkNum.Add(i);//服务器已经存在的区块编号
j++;
}
}
obj.Message = string.Format("服务器已经存在区块数量{0},总区块数量{1},占比{2}%", j
, chunks + , chunks != && j != ? Convert.ToDouble(Convert.ToDouble(j) / Convert.ToDouble(chunks)) * : );
return obj;
}
        /// <summary>
/// 文件上传、保存
/// </summary>
/// <param name="request"></param>
/// <param name="savepath"></param>
/// <returns></returns>
public static UploaderResult UploadSingleProcess(HttpRequestBase request, string savepath = null)
{
UploaderResult obj = new UploaderResult();
if (request.Files.Count == )
{
obj.Message = "请求中不包含文件流信息";
return obj;
}
if (request["size"] == null)
{
obj.Message = "文件大小为空";
return obj;
}
string tempFilePath = savepath + "temp\\" + request["md5"] + "\\";
string saveFilePath = savepath + "files\\";
if (!Directory.Exists(saveFilePath))
{
Directory.CreateDirectory(saveFilePath);
}
//判断是否分片,若文件大小不足分片,则直接保存
if (request.Form.AllKeys.Any(m => m == "chunk"))
{
//分片时创建临时文件目录
if (!Directory.Exists(tempFilePath))
{
Directory.CreateDirectory(tempFilePath);
}
//取得chunk和chunks
int chunk = Convert.ToInt32(request.Form["chunk"]);
int chunks = Convert.ToInt32(request.Form["chunks"]);
HttpPostedFileBase file = request.Files[];
//根据GUID创建用该GUID命名的临时文件
file.SaveAs(tempFilePath + chunk.ToString());
//判断是否所有的分块都已经上传完毕
string[] fileArr = Directory.GetFiles(tempFilePath);
if (fileArr.Length == chunks) {
obj.IsOver = true;
}
}
else
{
request.Files[].SaveAs(saveFilePath + request.Files[].FileName);
obj.IsOver = true;
}
return obj;
}
        /// <summary>
/// 文件块合并
/// </summary>
/// <returns></returns>
public ActionResult MergeFiles()
{
string ext = Request.Form["fileExt"];
string fileName = Request.Form["fileName"];
string chunkNum = Request.Form["chunkNum"];
string md5 = Request.Form["md5"];
string tempFilePath = this.RootFolder + "\\temp\\" + md5 + "\\";
string saveFilePath = this.RootFolder + "\\files\\" + fileName;
string[] fileArr = Directory.GetFiles(tempFilePath);
try
{
lock (tempFilePath)
{
if (Convert.ToInt32(chunkNum) == fileArr.Length)
{
if (System.IO.File.Exists(saveFilePath))
{
System.IO.File.Delete(saveFilePath);
}
FileStream addStream = new FileStream(saveFilePath, FileMode.Append, FileAccess.Write);
BinaryWriter AddWriter = new BinaryWriter(addStream);
for (int i = ; i < fileArr.Length; i++)
{
//以小文件所对应的文件名称和打开模式来初始化FileStream文件流,起读取分割作用
FileStream TempStream = new FileStream(tempFilePath+i, FileMode.Open);
//用FileStream文件流来初始化BinaryReader文件阅读器,也起读取分割文件作用
BinaryReader TempReader = new BinaryReader(TempStream);
//读取分割文件中的数据,并生成合并后文件
AddWriter.Write(TempReader.ReadBytes((int)TempStream.Length));
//关闭BinaryReader文件阅读器
TempReader.Close();
TempStream.Close();
}
AddWriter.Close();
addStream.Close();
AddWriter.Dispose();
addStream.Dispose();
Directory.Delete(tempFilePath, true);
}
//验证文件的MD5,确定文件的完整性 前端文件MD5值与后端合并的文件MD5值不相等
//if (UploaderHelper.GetMD5HashFromFile(saveFilePath) == md5)
//{
// int i = 1;
//}
return Json("{hasError:\"false\"}");
}
}
catch (Exception ex)
{
return Json("{hasError:\"true\"}");
}
}

后台代码,还需要整理优化,当然如果有问题,大家可以一块学习谈论。

webUploader上传组件 实际运用小结的更多相关文章

  1. SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片

    SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片   在上一篇文章中,我们介绍了< SpringMVC上传图片的常规上传方法 >.本文接着第一 ...

  2. webuploader 上传文件 生成链接下载文件

    最近 在asp.net MVC 项目 需要实现一个Excel和 图片上传功能.之前有使用过SWFUpload 做过上传图片功能,在本次实现过程中,有人推荐WebUploader 上传组件,因此采用we ...

  3. Baidu WebUploader 前端文件上传组件的使用

    简介 WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流I ...

  4. 百度上传组件 WebUploader

    WebUploader http://fex.baidu.com/webuploader/doc/index.html WebUploader API 文档详细解读 源码以及示例:https://gi ...

  5. 从零开始编写自己的C#框架(23)——上传组件使用说明

    文章导航 1.前言 2.上传组件功能说明 3.数据库结构 4.上传配置管理 5.上传组件所使用到的类 6.上传组件调用方法 7.效果演示 8.小结 1.前言 本系列所使用的是上传组件是大神July开发 ...

  6. webuploader上传文件,图片

    WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.官方地址:http://fex.baidu.com/webupload ...

  7. webuploader 上传文件参数设置

    webUploader 是款很好用的优秀的开源上传组件,由百度公司开发,详细的介绍可参见webUploader 的官方文档: 最近在使用webUploader时,需要添加额外的参数,并在后台获取,参数 ...

  8. Web Uploader - 功能齐全,完美兼容 IE 的上传组件

    文件上传是网站和 Web 应用程序的常用功能,一直没有一款完美的文件上传组件,因此让很多开发人员碰到头疼的浏览器兼容问题. WebUploader 是由 Baidu FEX 团队开发的一款以 HTML ...

  9. vue文件夹上传组件选哪个好?

    一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传:支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输. ...

随机推荐

  1. ios7控件特性(一)

    苹果发布iOS7之后,iOS7全部采用扁平化的界面,我们的app界面在iOS7上出现了很大的改变,这包括UINavigationBar,UIButton,UIActionSheet,UITabBar等 ...

  2. importExcel运用注解实现EXCEL导入poi类

    JAVA报表 package com.app.common.excel; import java.io.File; import java.io.FileInputStream; import jav ...

  3. 【UVALive - 3713】Astronauts (2-SAT)

    题意: 有n个宇航员,按照年龄划分,年龄低于平均年龄的是年轻宇航员,而年龄大于等于平均年龄的是老练的宇航员. 现在要分配他们去A,B,C三个空间站,其中A站只有老练的宇航员才能去,而B站是只有年轻的才 ...

  4. 【POJ2417】baby step giant step

    最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step ...

  5. Keil C51调试程序时, 对ROM的查看以及RAM 查看或修改

    在Keil 里使用 DeBug 模式时,如要 查看外部 RAM 的数据 或查看 ACC 的内容可以进行以下操作; sysGetTxMode: LCALL Com0185(C:2B95) ,sysGet ...

  6. spring 动态数据源

    1.动态数据源:  在一个项目中,有时候需要用到多个数据库,比如读写分离,数据库的分布式存储等等,这时我们要在项目中配置多个数据库. 2.原理:   (1).spring 单数据源获取数据连接过程: ...

  7. android和struts2实现android文件上传

    1.开发准备如下2个工具类 package org.lxh.util; import java.io.BufferedReader; import java.io.InputStreamReader; ...

  8. PL/SQL游标使用

    游标是用来处理使用SELECT语句从数据库中检索到的多行记录的工具.借助游标的功能,数据库应用程序可以对一组记录逐个进行处理,每次处理一行. 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中 ...

  9. 【HDOJ】1325 Is It A Tree?

    并查集.需要考虑入度. #include <stdio.h> #include <string.h> #define MAXNUM 10005 int bin[MAXNUM]; ...

  10. 悟透Javascript undefined,null,"",0这四个值转换为逻辑值时就是false &this关键字

    话题一:undefined,null,"",0这四个值转换为逻辑值时就是false 也就是在if判断时会把上面的五个作为false来判断.但是它们的类型确是不尽相同的,如下所示. ...