asp.net 文件分片上传
最近在研究文件上传,里面的门道还是挺多的,网上大多数文章比较杂乱,代码都是片段,对于新手小白来说难度较高,所以在此详细写一下今天看到的一个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 文件分片上传的更多相关文章
- Webuploader 大文件分片上传
百度Webuploader 大文件分片上传(.net接收) 前阵子要做个大文件上传的功能,找来找去发现Webuploader还不错,关于她的介绍我就不再赘述. 动手前,在园子里找到了一篇不错的分片 ...
- Vue2.0结合webuploader实现文件分片上传
Vue项目中遇到了大文件分片上传的问题,之前用过webuploader,索性就把Vue2.0与webuploader结合起来使用,封装了一个vue的上传组件,使用起来也比较舒爽. 上传就上传吧,为什么 ...
- java springboot 大文件分片上传处理
参考自:https://blog.csdn.net/u014150463/article/details/74044467 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时 ...
- vue+大文件分片上传
最近公司在使用vue做工程项目,实现大文件分片上传. 网上找了一天,发现网上很多代码都存在很多问题,最后终于找到了一个符合要求的项目. 工程如下: 对项目的大文件上传功能做出分析,怎么实现大文件分片上 ...
- plupload 大文件分片上传与PHP分片合并探索
最近老大分给我了做一个电影cms系统,其中涉及到一个功能,使用七牛云的文件上传功能.七牛javascript skd,使用起来很方便,屏蔽了许多的技术细节.如果只满足与调用sdk,那么可能工作中也就没 ...
- 利用blob对象实现大文件分片上传
首先说分片上传,我们在进行文件上传的时候,因为服务器的限制,会限制每一次上传到服务器的文件大小不会很大,这个时候我们就需要把一个需要上传的文件进行切割,然后分别进行上传到服务器. 假如需要做到这一步, ...
- iOS大文件分片上传和断点续传
总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...
- js实现大文件分片上传的方法
借助js的Blob对象FormData对象可以实现大文件分片上传的功能,关于Blob和FormData的具体使用方法可以到如下地址去查看FormData 对象的使用Blob 对象的使用以下是实现代码, ...
- Node + js实现大文件分片上传基本原理及实践(一)
_ 阅读目录 一:什么是分片上传? 二:理解Blob对象中的slice方法对文件进行分割及其他知识点 三. 使用 spark-md5 生成 md5文件 四. 使用koa+js实现大文件分片上传实践 回 ...
随机推荐
- ASP.NET Core Web API 集成测试中使用 Bearer Token
在 ASP.NET Core Web API 集成测试一文中, 我介绍了ASP.NET Core Web API的集成测试. 在那里我使用了测试专用的Startup类, 里面的配置和开发时有一些区别, ...
- BeetleX之HttpClusterApi应用详解
之前的文章已经介绍过如何使用HttpClusterApi进行去中心化的HTTP集群服务访问,这一章主要详细讲述如何使用HttpClusterApi,主要包括如何定义节点,创建服务接口和使用接口描述不同 ...
- Redis五大数据类型的常用操作
在上一篇博文<centos安装redis>中,已经详细介绍了如何在centos上安装redis,今天主要介绍下Redis五大数据类型及其五大数据类型的相关操作. Redis支持五种数据类型 ...
- Android序列化
1.序列化的目的 (1)永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中 (2)通过序列化对象在网络中传递对象 (3)通过序列化对象在进程间传递 (4)在Intent之间,基本的数据类型直接 ...
- redis的持久化方式RDB和AOF的区别
1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...
- jQuery(三)、属性、CSS
jQuery设置了很多为标签进行属性的操作,比如添加.删除. 一 .属性 1 attr(name | properties | [key, value | fn]) 设置或返回被选择的属性值. 参数: ...
- C++系列总结——封装
前言 众所周知,封装.继承和多态是面向对象编程的三大特性.C++作为一门面向对象的编程语言,自然支持了这些特性,但C++是如何实现这些特性的呢?今天先说下我理解的封装. 封装 通常我们会把下面的行为也 ...
- 解释器模式 Interpreter 行为型 设计模式(十九)
解释器模式(Interpreter) 考虑上图中计算器的例子 设计可以用于计算加减运算(简单起见,省略乘除),你会怎么做? 你可能会定义一个工具类,工具类中有N多静态方法 比如定义了两个 ...
- dedecms织梦上下页标签和CSS
模板中的分页部分源码: <div class="pagination-wrapper" style= "font-size:20pt;color:red;text- ...
- 如何将Eclipse的javaWeb项目改为IDEA的maven项目
1.首先去IDEA开发工具创建一个maven项目,把该项目改为Web项目, a.在pom.xml中,添加packaging标签,值为war b.右键File,选中project structure, ...