本篇教程探讨了HTML5教程 如何拖拽上传大文件,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 。
<
前言:
大文件传输一直是技术上的一大难点。文件过大时,一些性提交所有的内容进内存是不现实的。大文件带来问题还有是否支持断点传输和多文件同时传输。
本文以resumableJs为例,介绍了如何在中实现大文件传输。同时本文利用了Html5的新特性:支持拖拽。
本文的主要技术点在于:如何接收resumableJs的传送内容(官网不太清楚)和如何合并文件,难度并不高。
注:原博客中,此文章为原站点个人代码备份所用,注释不多,如有不懂,请在评论中给出。
效果:
ASPXFile:
Resumable.jsTest
welcome
varshowInfo=function(msg){
document.getElementById("info").innerHTML=msg;
}
showInfo("Testbegin");
varr=newResumable({
target:‘FileHandler.ashx‘,
});
r.assignBrowse(document.getElementById(‘container‘));
r.assignDrop(document.getElementById(‘container‘));
if(!r.support)showInfo("notsupport");
r.on(‘fileAdded‘,function(file,event){
r.upload();
});
r.on(‘filesAdded‘,function(array){
for(vari=0;i
varhtml=document.getElementById("info").innerHTML;
html+="
"+array[i].name;
}
});
r.on(‘uploadStart‘,function(){
showInfo(‘start‘);
});
r.on(‘complete‘,function(){
r.files.pop();
//ifwanttouploadonefilemultipletimes,youshouldremoveitfromr.filesaftercompleting.
//pop后,才可再次重新拖拽上传此文件。此机制可避免一次上传多个文件时重复添加,但拖拽上传时不用检测。
});
r.on(‘progress‘,function(e){
showInfo(r.progress());
});
FileHandler
usingSystem;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Web;
namespaceUploadTest
{
///
///SummarydescriptionforFileHandler
///
publicclassFileHandler:IHttpHandler
{
string_tempFolder;
object_lock=newobject();
publicvoidProcessRequest(HttpContextcontext)
{
_tempFolder=context.Server.MapPath("~/temp");
varmethod=context.Request.HttpMethod;
if(method.Equals("GET"))
{
HandleGet(context);
}
if(method.Equals("POST"))
{
HandlePost(context);
}
}
privatevoidHandlePost(HttpContextcontext)
{
varqueryString=context.Request.Form;
if(queryString.Count==0)return;
try
{
//Readparameters
varuploadToken=queryString.Get("upload_Token");
intresumableChunkNumber=int.Parse(queryString.Get("resumableChunkNumber"));
varresumableTotalChunks=int.Parse(queryString.Get("resumableTotalChunks"));
varresumableTotalSize=long.Parse(queryString.Get("resumableTotalSize"));
varresumableFilename=queryString.Get("resumableFilename");
//SaveFile
if(context.Request.Files.Count==0)
{
context.Response.StatusCode=(int).HttpStatusCode.InternalServerError;
}
else
{
varfilePath=string.Format("{0}/{1}/{1}.part{2}",_tempFolder,resumableFilename,resumableChunkNumber.ToString("0000"));
vardirectory=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(Exceptionexception)
{
throwexception;
}
}
privatevoidHandleGet(HttpContextcontext)
{
varqueryString=context.Request.QueryString;
if(queryString.Count==0)return;
try
{
//Readparameters
varuploadToken=queryString.Get("upload_Token");
intresumableChunkNumber=int.Parse(queryString.Get("resumableChunkNumber"));
varresumableFilename=queryString.Get("resumableFilename");
varresumableChunkSize=long.Parse(queryString.Get("resumableChunkSize"));
varfilePath=string.Format("{0}/{1}/{1}.part{2}",_tempFolder,
resumableFilename,resumableChunkNumber.ToString("0000"));
//Checkforexistanceandchunksize
if(System.IO.File.Exists(filePath)&&newFileInfo(filePath).Length==resumableChunkSize)
{
context.Response.Status="200OK";
context.Response.StatusCode=200;
}
else
{
context.Response.Status="404NotFound";
context.Response.StatusCode=404;
}
}
catch(Exceptionexception)
{
throwexception;
}
}
privateboolIsCompleted(stringdirectory,intnumChunks,longtotalSize)
{
varphysicalFolder=bine(_tempFolder,directory);
varfiles=Directory.GetFiles(physicalFolder);
//numbers
if(files.Length!=numChunks)
returnfalse;
//filesallexisit
varfileName=Path.GetFileName(directory);
for(inti=1;i<=numChunks;i++)
{
varfilePath=string.Format("{0}/{1}.part{2}",directory,fileName,i.ToString("0000"));
if(!File.Exists(filePath))
{
returnfalse;
}
}
//size
longtmpSize=0;
foreach(varfileinfiles)
{
tmpSize+=newFileInfo(file).Length;
}
returntotalSize==tmpSize;
}
privatevoidMergeFiles(stringdirectoryPath)
{
lock(_lock)
{
if(Directory.Exists(directoryPath))
{
varfileName=Path.GetFileName(directoryPath);
varfolder=Path.GetDirectoryName(directoryPath);
vartempPath=bine(directoryPath+".tmp");
varfiles=Directory.GetFiles(directoryPath);
files=files.OrderBy(f=>f).ToArray();
FileStreamwholeStream=newFileStream(tempPath,FileMode.Append,FileAccess.Write);
for(inti=0;i
{
FileStreamparcialStream=newFileStream(files[i],FileMode.Open);
BinaryReaderparcialReader=newBinaryReader(parcialStream);
byte[]buffer=newbyte[parcialStream.Length];
buffer=parcialReader.ReadBytes((int)parcialStream.Length);
BinaryWriterparcialWriter=newBinaryWriter(wholeStream);
parcialWriter.Write(buffer);
parcialStream.Close();
}
wholeStream.Close();
Directory.Delete(directoryPath,true);
File.Move(tempPath,directoryPath);
}
}
}
publicboolIsReusable
{
get
{
returnfalse;
}
}
}
}
附录:
1技术难点
a.文件过大。修改webconfig无用。
b.断点续传。
c.多文件上传。
2resumable.js
API:/
工作流程:
拖文件至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频道!