在传统的HTTP应用上 传文件 想要同时上传多个文件并查看上传 进度 是一件很麻烦的事情,当然现在也有一些基于SWF的文件上传组件提供这种的便利性.到了HT ML 5下对文件的读取和上传的控制方面就非常灵活,HTML5提供一 系列 的 ai P进行文件读取,包括计取文件某 一块 的内容也非常方便,结合Websocket进行文件的传输就变得更加方便和灵活.下面通过使用HTML5结合websocet 简单 地实现多文件同时上传应用.
实现功能
大概预览一下需要做的功能:
主要功能是用户可以直接把文件夹的文件直接拖放到网页中,并进行上传,在上传的 过程中 显示上传进度信息.
Fil ei nfo类封装
为了方便读取 文件信息 ,在原有File的基础封装了一个简单文件信息读取的对象类.
function FileInfo(file, pagesize) {
this.Size = file.size;
this.File = file;
this.FileTy PE = file.type;
this.FileN am e = file.name;
this.PageSize = pagesize;
this.PageIndex = 0;
this.Pages = 0;
this.UploadError = null;
this.Upload PR ocess = null;
this.DataBuffer = null;
this.UploadBytes = 0;
this.ID = Math.floor(Math.random() * 0 X10 000).toString(16);
this.LoadCallBack = null;
if (Math.floor(this.Size % this.PageSize) > 0) {
this.Pages = Math.floor((this.Size / this.PageSize)) + 1;
}
else {
this.Pages = Math.floor(this.Size / this.PageSize);
}
}
FileInfo.prototype.Reset = function () {
this.PageIndex = 0;
this.UploadBytes = 0;
}
FileInfo.prototype.toBase64String = function () {
VAR binary = ''
var bytes = new Uint8Array(this.DataBuffer)
var len = bytes.byteLength;
for (var i = 0; i < len; i++ ) {
binary += String. From CharCode(bytes[i])
}
return window. BT oa(binary);
}
FileInfo.prototype.OnLoadData = function (evt) {
var obj = evt.t arg et["tag"];
if (evt.target.ready stat e == FileReader.DONE) {
obj.DataBuffer = evt.target.result;
if (obj.LoadCallBack != null)
obj.LoadCallBack(obj);
}
else {
if (obj.UploadError != null)
obj.UploadError(fi, evt.target.error);
}
}
FileInfo.prototype.Load = function ( complete d) {
this.LoadCallBack = completed;
if (this.filereader == null || this.filereader == un define d)
this.filereader = new FileReader();
var reader = this.filereader;
reader["tag"] = this;
reader.onloadend = this.OnLoadData;
var count = this.Size - this.PageIndex * this.PageSize;
if (count > this.PageSize)
count = this.PageSize;
this.UploadBytes += count;
var blob = this.File.slice(this.PageIndex * this.PageSize, this.PageIndex * this.PageSize + count);
reader.readAsArrayBuffer(blob);
};
FileInfo.prototype.OnUploadData = function (file) {
var channel = file._channel;
var url = file._url;
channel.Send({ url: url, parameters: { FileID: file.ID, PageIndex: file.PageIndex, Pages: file.Pages, Base64Data: file.toBase64String()} }, function (result) {
if (result.status == null || result.status == undefined) {
file.PageIndex++;
if (file.UploadProcess != null)
file.UploadProcess(file);
if (file.PageIndex < file.Pages) {
file.Load(file.OnUploadData);
}
}
else {
if (file.UploadError != null)
file.UploadError(file, data.status);
}
});
}
FileInfo.prototype.Upload = function (channel, url) {
var fi = this;
channel.Send({ url: url, parameters: { FileName: fi.FileName, Size: fi.Size, FileID: fi.ID} }, function (result) {
if (result.status == null || result.status == undefined) {
fi._channel = channel;
fi._url = result.data;
fi.Load(fi.OnUploadData);
}
else {
if (file.UploadError != null)
file.UploadError(fi, result.status);
}
});
}
@H_ 360 _25@
类的处理很简单,通过file初始化并指定分块大小来实始化一些文件信息,如页数量页大小等.当然最 重要 还封装文件对应的Upload方法,用于把文件块信息打包成base64信息通过Websocket的方式发送到 服务器 .
文件拖放
在HTML5中接受 系统文件 拖放进来并不需要做复杂的事情,只需要针对容器元素绑定相关事件即可.
function on Drag Enter(e) {
e.stopPropagation();
e.p rev entDefault();
}
function onDragOver(e) {
e.stopPropagation();
e.preventDefault();
$(dropbox).addClass('rounded');
}
function onDragLeave(e) {
e.stopPropagation();
e.preventDefault();
$(dropbox).removeClass('rounded');
}
function onDrop(e) {
e.stopPropagation();
e.preventDefault();
$(dropbox).removeClass('rounded');
var rea DF ileSize = 0;
var files = e.data transfer .files;
if (files.length > 0) {
onFileOpen(files);
}
}
只需要在onDrop过程中获取相关拖放文件即可,这些可能通过一些HTML5的教程可以得到帮助。
这时候只需要针对选择的文件构建相关FileInfo对象,并调用上传方法即可.
function onFileOpen(files) {
if (files.length > 0) {
for (var i = 0; i < files.length; i++) {
var info = new FileInfo(files[i], 32768);
uploads.push(info);
info.UploadProcess = onUploadProcess;
addUpload IT em(info);
}
}
}
通过UploadProcess事件对上传文件进度信息进行一个设置更新
function onUploadProcess(file) {
$(' # p_' + file.ID).progressbar({ value: (file.PageIndex / file.Pages) * 100,
text: file.FileName + '[' + file.UploadBytes + '/' + file.Size + ']'
});
}
C#服务端
借助于Beetle对websocket的支持对应服务端的实现就非常简单了
/// <summary>
/// Copyright © henry fan 2012
///CreateTime: 2012/12/14 21:13:34
/// </summary>
p ub lic class Handler
{
public void UploadPackage(string FileID, int PageIndex, int Pages, string Base64Data)
{
Console.WriteLine("FileID:{2},PageIndex:{0} Pages:{1} DataLength:{3}", PageIndex, Pages, FileID,Base64Data.Length);
}
public string UploadFile(string FileID, string FileName, long Size)
{
Console.WriteLine("FileID:{2},FileName:{0} Size:{1}", FileName, Size, FileID);
return "Handler.UploadPackage";
}
}
服务端方法有两个一个是上传文件请求,和一个上传文件块接收方法.
总结
只需要以上简单的代码就能实现多文件同时 上传功能 ,在这采用json来处理上传的信息,所以文件流要进行一个base64的编码处理,由于websocket浏览提交的数据一般都有MASK处理再加上base64那损耗相对来说比较重,实际上websocket有提供流的数据包格式(arraybuffer);当然这种处理在操作上就没有json来得方便简单.
下载代码: WebSocketUpload.rar &nbs p;
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
总结
以上是 为你收集整理的 HTML5+WebSocket实现多文件同时上传的实例 全部内容,希望文章能够帮你解决 HTML5+WebSocket实现多文件同时上传的实例 所遇到的问题。
如果觉得 网站内容还不错, 推荐好友。
查看更多关于HTML5+WebSocket实现多文件同时上传的实例的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did205526