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实现大文件分片上传实践 回 ...
随机推荐
- Android开发:Android Studio开发环境配置
一.android studio下载: 1.Windows版: 下载地址:https://pan.baidu.com/s/1-sg4dN_2B5nn2YJf-C7XLQ 提取码:yedc 2.Mac版 ...
- python进程和线程(六)
协程 协程,又称微线程,纤程.英文名Coroutine.顾名思义,协程是协作式的,也就是非抢占式的程序(线程是抢占式的).协程的关键字是yield,一看到这个就想到了生成器对不对?那就顺便回顾一下生成 ...
- 从壹开始前后端分离 [ Vue2.0+.NetCore2.1] 二十六║Client渲染、Server渲染知多少{补充}
前言 书接上文,昨天简单的说到了 SSR 服务端渲染的相关内容<二十五║初探SSR服务端渲染>,主要说明了相关概念,以及为什么使用等,昨天的一个小栗子因为时间问题,没有好好的给大家铺开来讲 ...
- 我眼中的 Nginx(一):Nginx 和位运算
作者张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技 ...
- 使用chan的时候选择对象还是指针
使用chan的时候选择对象还是指针 今天在写代码的时候遇到一个问题,在创建一个通道的时候,不确定创建的通道是使用chan A还是chan *A. 思考了一下,觉得这个应该和函数一样是一个值传递还是参数 ...
- .NET Core 使用NLog日志记录
前言 每个项目都会需要使用到日志功能,这对于项目上线后 出现的bug异常,能及时定位和便于后期错误分析.那我们今天来看看在.NET Core中如何使用NLog日志. NLog 什么是NLog呢? NL ...
- SmartSql Cache标签
Demo <Cache Id="T_Test.LruCache" Type="Lru"> <Parameter Key="Cache ...
- .Net Core的Log方式:Serilog+Kibana
前言 Serilog,支持对象,把log数据序列化成Json,好用方便,容易拓展.Github: https://github.com/handsomeyao77/serilog-sinks-elas ...
- .NET redis cluster
一.下载Windows版本Redis 下载链接:https://github.com/MSOpenTech/redis/releases(根据系统选择对应版本) 二.修改默认的配置文件 如上图两个配置 ...
- jQuery里面的常用的事件和基础动画的实现
一:了解jquery里面常用的事件 二:了解基础动画的实现 1:加载DOM 在JavaScript中使用window.onload事件作为窗体加载事件(它在页面所有数据加载完成之后才会执行) 在jQu ...