zoukankan      html  css  js  c++  java
  • (转)大文件上传,支持续传(ASP.NET MVC2+Flex)

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

    分类: Flex .Net 1568人阅读 评论(3) 收藏 举报

     

    实现原理

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

    定义上传文件的服务端接口(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对象,可实现多个文件上传。

    优化上传效率:把文件分成几个大数据块,然后每个数据块分别上传,服务端管理各个大数据块的写入,确保最后能够从新拼接成原始文件。(类似多线程下载)

  • 相关阅读:
    第七次作业
    Beta敏捷冲刺每日报告——Day5
    Beta敏捷冲刺每日报告——Day4
    Beta敏捷冲刺每日报告——Day3
    Beta敏捷冲刺每日报告——Day2
    Beta敏捷冲刺每日报告——Day1
    MyGod--Beta版本前期报告
    第六次作业
    游标的使用
    Hadoop科普文——常见的45个问题解答
  • 原文地址:https://www.cnblogs.com/errorx/p/2761016.html
Copyright © 2011-2022 走看看