html5 上传超大文件,HTML5教程 如何拖拽上传大文件
本篇教程探讨了HTML5教程 如何拖拽上传大文件,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 。
<
前言:
大文件传输一直是技术上的一大难点。文件过大时,一些性提交所有的内容进内存是不现实的。大文件带来问题还有是否支持断点传输和多文件同时传输。
本文以resumableJs为例,介绍了如何在ASP.NET中实现大文件传输。同时本文利用了Html5的新特性:支持拖拽。
本文的主要技术点在于:如何接收resumableJs的传送内容(官网不太清楚)和如何合并文件,难度并不高。
注:原博客中,此文章为原站点个人代码备份所用,注释不多,如有不懂,请在评论中给出。
效果:
ASPX File:
Resumable.js Test
welcome
var showInfo = function (msg) {
document.getElementById("info").innerHTML = msg;
}
showInfo("Test begin");
var r = new Resumable({
target: ‘FileHandler.ashx‘,
});
r.assignBrowse(document.getElementById(‘container‘));
r.assignDrop(document.getElementById(‘container‘));
if (!r.support) showInfo("not support");
r.on(‘fileAdded‘, function (file, event) {
r.upload();
});
r.on(‘filesAdded‘, function (array) {
for (var i = 0; i
var html = document.getElementById("info").innerHTML;
html += "
"+array[i].name;
}
});
r.on(‘uploadStart‘, function () {
showInfo(‘start‘);
});
r.on(‘complete‘, function () {
r.files.pop();
//if want to upload one file multiple times, you should remove it from r.files after completing.
//pop后,才可再次重新拖拽上传此文件。此机制可避免一次上传多个文件时重复添加,但拖拽上传时不用检测。
});
r.on(‘progress‘, function (e) {
showInfo(r.progress());
});
FileHandler
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
namespace UploadTest
{
///
/// Summary description for FileHandler
///
public class FileHandler : IHttpHandler
{
string _tempFolder;
object _lock = new object();
public void ProcessRequest(HttpContext context)
{
_tempFolder = context.Server.MapPath("~/temp");
var method = context.Request.HttpMethod;
if (method.Equals("GET"))
{
HandleGet(context);
}
if (method.Equals("POST"))
{
HandlePost(context);
}
}
private void HandlePost(HttpContext context)
{
var queryString = context.Request.Form;
if (queryString.Count == 0) return;
try
{
// Read parameters
var uploadToken = queryString.Get("upload_Token");
int resumableChunkNumber = int.Parse(queryString.Get("resumableChunkNumber"));
var resumableTotalChunks = int.Parse(queryString.Get("resumableTotalChunks"));
var resumableTotalSize = long.Parse(queryString.Get("resumableTotalSize"));
var resumableFilename = queryString.Get("resumableFilename");
// Save File
if (context.Request.Files.Count == 0)
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
}
else
{
var filePath = string.Format("{0}/{1}/{1}.part{2}", _tempFolder, resumableFilename, resumableChunkNumber.ToString("0000"));
var directory = Path.GetDirectoryName(filePath);
if (File.Exists(directory))
{
File.Delete(directory);
}
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (!System.IO.File.Exists(filePath))
{
context.Request.Files[0].SaveAs(filePath);
}
if (IsCompleted(directory,resumableTotalChunks,resumableTotalSize))
{
MergeFiles(directory);
}
}
}
catch (Exception exception)
{
throw exception;
}
}
private void HandleGet(HttpContext context)
{
var queryString = context.Request.QueryString;
if (queryString.Count == 0) return;
try
{
// Read parameters
var uploadToken = queryString.Get("upload_Token");
int resumableChunkNumber = int.Parse(queryString.Get("resumableChunkNumber"));
var resumableFilename = queryString.Get("resumableFilename");
var resumableChunkSize = long.Parse(queryString.Get("resumableChunkSize"));
var filePath = string.Format("{0}/{1}/{1}.part{2}", _tempFolder,
resumableFilename, resumableChunkNumber.ToString("0000"));
// Check for existance and chunksize
if (System.IO.File.Exists(filePath) && new FileInfo(filePath).Length == resumableChunkSize)
{
context.Response.Status = "200 OK";
context.Response.StatusCode = 200;
}
else
{
context.Response.Status = "404 Not Found";
context.Response.StatusCode = 404;
}
}
catch (Exception exception)
{
throw exception;
}
}
private bool IsCompleted(string directory,int numChunks, long totalSize )
{
var physicalFolder = Path.Combine(_tempFolder, directory);
var files = Directory.GetFiles(physicalFolder);
//numbers
if (files.Length != numChunks)
return false;
//files all exisit
var fileName = Path.GetFileName(directory);
for (int i = 1; i <= numChunks; i++)
{
var filePath = string.Format("{0}/{1}.part{2}", directory, fileName, i.ToString("0000"));
if (!File.Exists(filePath))
{
return false;
}
}
//size
long tmpSize = 0;
foreach (var file in files)
{
tmpSize += new FileInfo(file).Length;
}
return totalSize==tmpSize;
}
private void MergeFiles(string directoryPath)
{
lock (_lock)
{
if (Directory.Exists(directoryPath))
{
var fileName = Path.GetFileName(directoryPath);
var folder = Path.GetDirectoryName(directoryPath);
var tempPath = Path.Combine(directoryPath + ".tmp");
var files = Directory.GetFiles(directoryPath);
files = files.OrderBy(f => f).ToArray();
FileStream wholeStream = new FileStream(tempPath, FileMode.Append, FileAccess.Write);
for(int i=0;i
{
FileStream parcialStream = new FileStream(files[i], FileMode.Open);
BinaryReader parcialReader = new BinaryReader(parcialStream);
byte[] buffer = new byte[parcialStream.Length];
buffer = parcialReader.ReadBytes((int)parcialStream.Length);
BinaryWriter parcialWriter = new BinaryWriter(wholeStream);
parcialWriter.Write(buffer);
parcialStream.Close();
}
wholeStream.Close();
Directory.Delete(directoryPath,true);
File.Move(tempPath, directoryPath);
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
附录:
1 技术难点
a. 文件过大。修改webconfig无用。
b. 断点续传。
c. 多文件上传。
2 resumable.js
API: http://www.resumablejs.com/
工作流程:
拖文件至DIV -> 开始上传,uploadStart -> 反复触发progress事件 -> compete
主要参数:
Get:
resumableChunkNumber=1&
resumableChunkSize=1048576&
resumableCurrentChunkSize=1048576&
resumableTotalSize=27778318&
resumableType=&
resumableIdentifier=27778318-Samples7z&
resumableFilename=Samples.7z&
resumableRelativePath=Samples.7z&
resumableTotalChunks=26
Post:
—————————–111061030216033
Content-Disposition: form-data; name=”resumableChunkNumber”
140
—————————–111061030216033
Content-Disposition: form-data; name=”resumableChunkSize”
1048576
—————————–111061030216033
Content-Disposition: form-data; name=”resumableCurrentChunkSize”
1048576
—————————–111061030216033
Content-Disposition: form-data; name=”resumableTotalSize”
171309601
—————————–111061030216033
Content-Disposition: form-data; name=”resumableType”
—————————–111061030216033
Content-Disposition: form-data; name=”resumableIdentifier”
171309601-sample7z
—————————–111061030216033
Content-Disposition: form-data; name=”resumableFilename”
sample.7z
—————————–111061030216033
Content-Disposition: form-data; name=”resumableRelativePath”
sample.7z
—————————–111061030216033
Content-Disposition: form-data; name=”resumableTotalChunks”
163
—————————–111061030216033
Content-Disposition: form-data; name=”file”; filename=”blob”
Content-Type: application/octet-stream
XXXCONTENT
—————————–309022088923579–
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端HTML5/CSS3频道!
html5 上传超大文件,HTML5教程 如何拖拽上传大文件相关推荐
- vue-simple-uploader实现多文件/文件夹以及可拖拽上传
vue-simple-uploader的简单使用 1.效果图展示 2.安装 3.vue2使用(vue3使用会报错) 4.代码 vue-simple-uploader是基于simple-uploader ...
- 拖拽上传技术-----html5[转载]
原网址:http://blog.163.com/mongying_net/blog/static/35112712012345352226/ 拖拽上传应用主要使用了以下HTML5技术: Drag&am ...
- 实现拖拽上传文件的一款小控件——dropzone
由于专注所以专业.非常多小巧的东西乍一看非常不起眼,却在特定的领域表现不俗,就是由于集中了热情. dropzone就是这样一款小控件,实现拖拽上传.它不依赖于其他像jquery等JS库.并且支持多方面 ...
- js实现文件拖拽上传并显示待上传的文件列表
此文章中完整的代码在我的github中:https://github.com/LiuFeng1011/WebTest/tree/master/upload 首先实现html页面的内容: <bod ...
- [开源应用]利用HTTPHandler+resumableJs+HTML5实现拖拽上传[大]文件
前言: 大文件传输一直是技术上的一大难点.文件过大时,一些性提交所有的内容进内存是不现实的.大文件带来问题还有是否支持断点传输和多文件同时传输. 本文以resumableJs为例,介绍了如何在ASP. ...
- html5之多文件拖拽上传预览
最近对于html5预览功能很是感兴趣,特地拿出来研究一小下,并以一个小项目举例讲解. h5中的input有个type=file 就是文件上传控件,有个属性multiple就是h5新增的支持多选上传文件 ...
- html ajax打包成app,利用HTML5与ajax完成拖拽上传文件
前言 基于ajax的异步模式的上传控件,基本功能如下: 拖拽上传(利用HTML5新增特定 拖拽事件 以及 event的dataTransfer属性) 单文件/多文件切换(利用php实现单/多文件上传) ...
- 使用jQuery开发一个基于HTML5的漂亮图片拖拽上传web应用
昨天我们介绍了一款HTML5文件上传的jQuery插件:jQuery HTML5 uploader,今天我们将开发一个简单的叫upload center的图片上传程序,允许用户使用拖拽方式来上传电脑上 ...
- Nodejs express、html5实现拖拽上传(转载)
一.前言 文件上传是一 个比较常见的功能,传统的选择方式的上传比较麻烦,需要先点击上传按钮,然后再找到文件的路径,然后上传.给用户体验带来很大问题.html5开始支持拖 拽上传的需要的api.node ...
最新文章
- 2021年大数据Hadoop(二十九):​​​​​​​关于YARN常用参数设置
- Flask-login Question
- HDU 6015 Skip the Class
- 学生、课程、分数的设计(重要)
- leetcode算法题--Flood Fill
- linux裸设备文件系统,Linux当中的文件系统
- 【数据竞赛】从0梳理1场数据挖掘赛事!
- gradle tool升级到3.0注意事项
- Bloom-Filter算法 简介
- Windows编程—Windows驱动中定时器的使用
- 【Java】计算一组同学一门课程的平均成绩、最高成绩和最低成绩
- 乔布斯首份手写求职信再次被拍卖
- 20200308——多项式回归预测工资
- Django生命周期,FBV,CBV
- linux中SPI相关API函数,linux spi驱动开发学习(一)-----spi子系统架构
- 《跨界杂谈》华为印象(二):MTS
- Codeforces Round #459 (Div. 1) B. MADMAX
- 《股市稳赚》书中的精髓:用简单的神奇公式进行股票投资,获得稳定而持久的收益。
- java中怎么保留小数_java怎么保留小数
- python 中文乱码问题
热门文章
- 快手二面:Java 里的 for (;;) 与 while (true),哪个更快?
- 这 HTTPS,真滴牛逼!
- 三次握手+四次挥手,一文搞定所有!历史最佳剖析!
- Kafka核心设计与实践原理总结:进阶篇
- 程序员吐槽:不和同事一起吃午饭,被领导批了!网友戏称:以后拉屎也要和同事一起,打成一片!...
- 推荐8个高质量的小众实用APP,解决你的痛点需求
- 通过OKR 进行项目过程管理
- -y表示自动安装,不需要每项手动确认输入 Yes
- 求主析取范式与主合取范式
- 一次特殊的经历和迷茫-小米平板