最近在研究文件上传,里面的门道还是挺多的,网上大多数文章比较杂乱,代码都是片段,对于新手小白来说难度较高,所以在此详细写一下今天看到的一个demo,关于文件分片上传的。

  

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
</head>
<body>
<input type="file" id="file6" multiple><button type="button" class="btnFile6">分片上传</button><div class="result"></div>
</body>
</html>
<script>
$(".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: "Handler.ashx",
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);
});
</script>

  后端一般处理程序:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web; namespace WebApplication1
{
/// <summary>
/// Handler 的摘要说明
/// </summary>
public class Handler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//保存文件到指定目录
var filePath = @"D:\penglong\study\WebApplication1\WebApplication1\uploads\" + context.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(context.Request.Files[].InputStream);
//将文件留转成字节数组
byte[] bytes = br.ReadBytes((int)context.Request.Files[].InputStream.Length);
//将字节数组追加到文件
bw.Write(bytes);
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}

  浏览器监听的请求过程如图:

  

  目前代码里设置的是1M一片,2.25MB的文件被分为了3片,因此请求的时候请求了三次,这样,我们就可以上传大文件了。(webconfig可以设置最大文件为2G,当上传的文件超过2G或者我们不希望更改webconfig配置时,则可以使用这个进行分片上传,网上大多数分片插件的原理也是如此,通过构造formdata对象进行多次上传,然后在后端进行文件的合并操作)。

  参考链接:https://www.cnblogs.com/fjzhang/p/7227401.html?utm_source=itdadao&utm_medium=referral


  补:

  从demo上讲,上面的案例基本没有问题,但是实际使用的场景中,会存在这样一个问题,由于文件是存在磁盘上的,当用户再次上传同名文件时,文件流会被继续追加到这个文件里,而不是另起一个文件,或者做覆盖操作,因为FileMode.Append模式下会检测当前路径是否存在这个文件,存在则append。

  那么该如何解决这个问题呢,一开始我想到的是通过size判断,如果传入文件的size,不等于读取到的文件流对象的大小,则说明文件还没有传输完毕,则可以继续append。但是当等于时,是需要新建文件的,所以就得重命名了,windows系统再重命名的时候会在原有文件名后面带上副本啊之类的名称,我这里为了简洁,直接在前端读取了一个系统时间作为唯一标识,来混入文件名,这样后台保存的文件就不会存在文件流并入一个文件的问题了。

     代码如图:

  

  

  这里有一点需要注意,为什么我不在后端去生成这个时间标识,而是在前端生成呢?原因是这里是进行分片上传的,会多次请求后端接口,如果在后端生成唯一标识,那么在上传文件的方法里会生成多个文件,这样是不对的,所以这里在前端做了参数取值,每次点击的时候生成一个唯一标识,即便分N次上传,名称也是同一个,文件流就能正常合并在一个文件里了。

  当然,关于这个同名文件上传改名的操作,后端应该也能完成,但是感觉过于复杂,这里就没有尝试。有兴趣的园友可以一起探讨思路。暂时就补充到这里了。

asp.net 文件分片上传的更多相关文章

  1. Webuploader 大文件分片上传

    百度Webuploader 大文件分片上传(.net接收)   前阵子要做个大文件上传的功能,找来找去发现Webuploader还不错,关于她的介绍我就不再赘述. 动手前,在园子里找到了一篇不错的分片 ...

  2. Vue2.0结合webuploader实现文件分片上传

    Vue项目中遇到了大文件分片上传的问题,之前用过webuploader,索性就把Vue2.0与webuploader结合起来使用,封装了一个vue的上传组件,使用起来也比较舒爽. 上传就上传吧,为什么 ...

  3. java springboot 大文件分片上传处理

    参考自:https://blog.csdn.net/u014150463/article/details/74044467 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时 ...

  4. vue+大文件分片上传

    最近公司在使用vue做工程项目,实现大文件分片上传. 网上找了一天,发现网上很多代码都存在很多问题,最后终于找到了一个符合要求的项目. 工程如下: 对项目的大文件上传功能做出分析,怎么实现大文件分片上 ...

  5. plupload 大文件分片上传与PHP分片合并探索

    最近老大分给我了做一个电影cms系统,其中涉及到一个功能,使用七牛云的文件上传功能.七牛javascript skd,使用起来很方便,屏蔽了许多的技术细节.如果只满足与调用sdk,那么可能工作中也就没 ...

  6. 利用blob对象实现大文件分片上传

    首先说分片上传,我们在进行文件上传的时候,因为服务器的限制,会限制每一次上传到服务器的文件大小不会很大,这个时候我们就需要把一个需要上传的文件进行切割,然后分别进行上传到服务器. 假如需要做到这一步, ...

  7. iOS大文件分片上传和断点续传

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  8. js实现大文件分片上传的方法

    借助js的Blob对象FormData对象可以实现大文件分片上传的功能,关于Blob和FormData的具体使用方法可以到如下地址去查看FormData 对象的使用Blob 对象的使用以下是实现代码, ...

  9. Node + js实现大文件分片上传基本原理及实践(一)

    _ 阅读目录 一:什么是分片上传? 二:理解Blob对象中的slice方法对文件进行分割及其他知识点 三. 使用 spark-md5 生成 md5文件 四. 使用koa+js实现大文件分片上传实践 回 ...

随机推荐

  1. docker 搭建私有仓库 harbor

    前提 已安装好 docker 和  docker-compose 环境:CentOS Linux release 7.5 docker 版本:18.09.05 1.安装harbor wget -P / ...

  2. logisim元件清单

  3. 谈谈axios配置请求头content-type

    现在前端开发中需要通过Ajax发送请求获取后端数据是很普遍的一件事情了,鉴于我平时在撸码中用的是vue技术栈,今天这里来谈谈我们常用的发Ajax请求的一个插件-axios. > 现在网上可能发送 ...

  4. KOA中间件的基本运作原理

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 在中 ...

  5. C#知识拾遗

    参数验证方式 1.    一般方法 1.1 手动验证 最为普遍常见,略. 1.2 使用扩展方法验证 在C#3.0 中,引入了扩展方法,可以以一种更优雅的方式来进行参数验证,如: //参数辅助类 pub ...

  6. c# List根据某个属性进行分类,变成以属性名称作为分类的多个List

    在平时的开发中,我们从数据库中得到List列表,但是我们希望可以根据属性名称再次进行分类. 其实LINQ中已经内置相应的算法. 长话短说,直接上代码: var dataList = JsonHelpe ...

  7. Redis Cluster搭建高可用Redis服务器集群

    一.Redis Cluster集群简介 Redis Cluster是Redis官方提供的分布式解决方案,在3.0版本后推出的,有效地解决了Redis分布式的需求,当一个节点挂了可以快速的切换到另一个节 ...

  8. spring boot 2.0 ribbon 负载均衡配置

    1.pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId ...

  9. jQuery(九)、ajax对象操作

    1 数组和对象操作 1.jQuery.extend([deep,] target, object1, [objectN]) 用一个或多个其他对象来扩展一个对象,返回被扩展的对象. 如果不指定targe ...

  10. Vue 无限滚动加载指令

    也不存在什么加载咯, 就是一个判断滚动条是否到达浏览器底部了. 如果到了就触发事件,米到就不处理. 计算公式提简单的   底部等于(0) =  滚动条高度 - 滚动条顶部距离 - 可视高度.  反正结 ...