1,是基于webUploader的前端开源插件实现的大大文件 分片上传功能:

  1. 四种文件上传格式(以后要改进的地方)

    1. 普通按钮点击上传

    2. 拖拽上传

    3. 复制粘贴上传

    4. 拖拽+按钮+复制粘贴上传

    5. 多线程上传文件


2,简单的文件分片合并上传原理:

借鉴的博客:  地址

前段页面


分片上传6
//方式6  $(".btnFile6").click(function () {       var upload = function (file, skip) {          var formData = new FormData();//初始化一个FormData对象          var blockSize = 1000000;//每块的大小          var nextSize = Math.min((skip + 1) * blockSize, file.size);//读取到结束位置                       var fileData = file.slice(skip * blockSize, nextSize);//截取 部分文件 块          formData.append("file", fileData);//将 部分文件 塞入FormData          formData.append("fileName", file.name);//保存文件名字          $.ajax({              url: "/Home/SaveFile6",              type: "POST",              data: formData,              processData: false,  // 告诉jQuery不要去处理发送的数据              contentType: false,   // 告诉jQuery不要去设置Content-Type请求头              success: function (responseText) {                  $(".result").html("已经上传了" + (skip + 1) + "块文件");                  if (file.size <= nextSize) {//如果上传完成,则跳出继续上传                      alert("上传完成");                      return;                  }                  upload(file, ++skip);//递归调用              }          });      };        var file = $("#file6")[0].files[0];      upload(file, 0);  });

后端代码

public string SaveFile6()
{
    //保存文件到根目录 App_Data + 获取文件名称和格式
    var filePath = Server.MapPath("~/App_Data/") + Request.Form["fileName"];
    //创建一个追加(FileMode.Append)方式的文件流
    using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            //读取文件流
            BinaryReader br = new BinaryReader(Request.Files[0].InputStream);
            //将文件留转成字节数组
            byte[] bytes = br.ReadBytes((int)Request.Files[0].InputStream.Length);
            //将字节数组追加到文件
            bw.Write(bytes);
        }
    }
    return "保存成功";
}

3,监控文件上传的三个时间点:(上传)本地项目实例

  1. 时间点1: 所有分块进行上传之前(1,算文件的唯一标识,2,判断文件是否秒传)

    1. 计算分片文件的MD5唯一标识,

    2. 请求后台是否保存过该文件,存在跳过该文件,不存在则继续上传.

  2. 时间点2: 如果分片上传, 每个分片上传之前(1, 通知询问后台是否已经保存成功, 用于断点续传)

    1. 每个每个分块有每个分块的下标和大小.

    1. 请求后台是否保存过当前分块,存在跳过该分片文件,实现断点续传

    2. 请求后台是否保存完成该文件信息,如果保存过,则跳过; 如果不存在或者不完整则发送该分块内容

    3. 携带当前文件的唯一标识到后台, 用于让后台创建保存该文件分块的目录

  3. 时间点3: 所有分块上传成功之后(1, 通知后台进行分块文件的合并工作)

    1. 前台通知后台合并文件


3,后台文件的处理:

  • java.lang.Object

    • java.nio.channels.spi.AbstractInterruptibleChannel

    • java.nio.channels.FileChannel 

  • 用于读取,写入,映射和操作文件的通道。

  • 用到这个方法

  • 将上传的分片放到零时的文件夹中,合并之后删除分片

  • // 输出流

FileChannel outChannel  = FileOutputStream(file).getChannel()FileChannel inChannel(File tmp : fileList) {
   inChannel = FileInputStream(tmp).getChannel()inChannel.transferTo(inChannel.size()outChannel)inChannel.close()file.delete()}
(outChannel != ) {
   (f)outChannel.close()}







文件上传的前端代码:









charset="UTF-8">

</span>webuploaderDemo<span class="html-tag">

rel="stylesheet" href="staticresource/layui/css/layui.css">

rel="stylesheet" href="staticresource/webuploader/upload.media.css">

rel="stylesheet" href="staticresource/css/style.css">












class="layui-btn layui-btn-danger layui-btn-sm" id="batchWebUpload">

class="layui-icon">划重点,多选,分片批量上传+断点续传







id="fileListDom" class="upload-table" style="display: none">

class="layui-btn layui-btn-danger layui-btn-sm" id="startAll" onclick="startAll()">

全部开始


class="layui-btn layui-btn-danger layui-btn-sm" id="stopAll" onclick="stopUpload()">

全部暂停


class="layui-table" lay-size="sm">width="200">width="150">width="150">width="350">width="150">width="200">width="450">id="fileList" class="fileQueue">id="fileInfo">













文件名

文件类型

文件大小

进度

百分比

状态

操作








 

  colspan="4">

  选中id="fileQueueNum">0个文件,共id="fileQueueSize">0M。

  上传成功id="successNum">0个文件,共id="successSize">0M。

 

 

  id="sumPercent">

 

 

  colspan="2">

 
class="layui-progress" lay-showPercent="yes" lay-filter="sumProgress">

class="layui-progress-bar" lay-percent="0%" id="sumProgress_bar" >


 

 







后端代码