您的位置:首页 > 编程语言 > ASP

大文件上传,支持续传(ASP.NET MVC2+Flex)

2010-11-28 18:31 176 查看

实现原理

客户端读取文件流,把文件分成多份数据,然后一份一份向服务端发送。服务端接收数据,写入到服务端文件。

定义上传文件的服务端接口(ASP.NET MVC2)

主要接口

获取上传文件:服务端生成一个文件名返回给客户端,确保所有用户上传时文件名不冲突。

分段上传文件:服务端接收后写入到文件流,返回服务端已上传的文件长度给客户端。

取消上传:删除服务端文件, 避免积累大量无效的上传文件。

FileUploadController源码:

using System;

using System.Web.Mvc;

using System.IO;



namespace DotNetMvc.Controllers

{

public class FileUploadController : Controller

{

// 自定义返回格式

private ActionResult JsonResult(object returnValue, int errorCode = 0, string errorMessage = "")

{

return Json(new

{

ErrorCode = errorCode,

ErrorMessage = errorMessage,

ReturnValue = returnValue

},

JsonRequestBehavior.AllowGet//允许Get调用,默认是不允许。

);

}

// 获取上传文件,由服务端决定上传文件命名策略

public ActionResult GetFile(string file)

{

string result = DateTime.Now.ToString("yyyy-MM-dd-") +

Path.GetFileNameWithoutExtension(file) + Guid.NewGuid().ToString().Replace("-", "") +

Path.GetExtension(file);



return JsonResult(result);// 返回文件名称

}

private string GetUploadFilePath(string file)

{

string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads//" + file);

return path;

}

// 分段上传文件

public ActionResult Upload(string file, long start, string base64)

{

string path = GetUploadFilePath(file);

byte[] bytes = Convert.FromBase64String(base64);

using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))

{

fs.Seek(start, SeekOrigin.Begin);

fs.Write(bytes, 0, bytes.Length);

fs.Close();

}

long result = start + bytes.Length;

return JsonResult(result);// 返回新文件长度

}

// 取消上传,删除上传文件

public ActionResult Cancel(string file)

{

string path = GetUploadFilePath(file);

System.IO.File.Delete(path);



return JsonResult(true);

}

// 自定义错误

public ActionResult Error(string message)

{

return JsonResult(null, 404, message);

}

// 捕捉未知错误

protected override void OnException(ExceptionContext filterContext)

{

base.OnException(filterContext);

Server.ClearError();

Response.Redirect("~/FileUpload/Error?message=" + Uri.EscapeDataString(filterContext.Exception.Message));

}

}

}

客户端调用上传接口 (Flex)

主要步骤

使用FileReference.browse()方法选择文件。

使用FileReference.load()方法加载本地文件。

通过FileReference.data属性访问加载的文件流,调用FileReference.load()后FileReference.data属性不会立即赋值,当Event.COMPLETE事件派发后data才赋值。

分段读取FileReference.data的bytes上传到服务端,数据传输时,bytes需要采用base64编码成字符串发送,服务端要进行base64解码。

效果图










总结

该上传方案的优点是支持大文件上传,支持续传,缺点是上传效率略低。

进阶

多文件上传:Flex客户端使用FileReferenceList对象,可实现多个文件上传。

优化上传效率:把文件分成几个大数据块,然后每个数据块分别上传,服务端管理各个大数据块的写入,确保最后能够从新拼接成原始文件。(类似多线程下载)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: