WEB版一次选择多个文件进行批量上传(Plupload)的解决方案

 转载自http://www.cnblogs.com/chillsrc/archive/2013/01/30/2883648.html

说明:Plupload支持多种浏览器,多种上传方式!

一般的WEB方式文件上传只能使用FileUpload控件进行一个文件一个文件的进行上传,就算是批量上传,也要把文件一个一个的添加到页面,无法如 windows程序一样,一次选择多个文件进行批量上传。这样在某些应用上就显得很不人性化,有时候客户希望能够一次选择很多文件,然后让系统把选择的文 件全部上传。本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案。见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案

由于上一个swfupload示例对于IE9的兼容性的不太好,以及随着HTML5与IE9、IE10的逐渐普及,加上鉴于swfupload已经很久没有进行过更新等等原因,要对批量文件上传的方案要进行更新,使用新的解决方案。于是在经过一阵寻找之后,决定使用plupload做为核心重新写了一个批量文件上传解决方案。

Plupload 是一个Web浏览器上的界面友好的文件上传组件,可显示上传进度、图像自动缩略和上传分块,同时上传多个文件。Plupload 的上传文件的引擎使用Flash,Silverlight,HTML5,Gears,BrowserPlus或正常的FileUpload。

Plupload组件是由TinyMCE开发者开发的Web文件上传组件,是一个高度可用的上传处理组件方便您添加到您的内容管理系统或类似的系统。Plupload目前分为核心API和一个jQuery上传队列组件,这使您可以使用现在组件或自己编写自己的自定义实现。Plupload使用GPLv2许可。

关于Plupload的功能说明:

Feature

Flash

Gears

HTML 5

Silverlight

BrowserPlus

HTML 4

Chunking

√1

X

Drag/Drop

X

√2

X

X

PNG Resize

√3

X

JPEG Resize

√3

X

Type filtering

√4

X

Stream upload

X

X

Multipart upload

√5

File size restriction

X

Upload progress

X

Custom headers

X

X

关于上表中的一些注意点说明:

1.Chunking is properly supported in Chrome. On most part in Firefox 4+.

分块功能支持的浏览器有:chrome,firefox 4以上版本

2.Drag/drop support of files is currently only available in Firefox and WebKit. Safari on Windows has some strange problems and requires workaround.

文件拖放功能目录只适用于Firefox和WebKit。Safari在Windows上有一些奇怪的问题,需要解决。

3.Image resizing is only possible on Firefox 3.5+ (with fixed quality) and Chrome. Safari/Opera doesn't support direct data access to the selected files.

图像缩放目前只是支持Firefox 3.5 +(固定质量)和Chrome两个浏览器。Safari和Opera不支持直接访问选定的文件。

4.File type filtering is currently not supported by all browsers. But we fill the HTML 5 accept attribute so once the support is there it will work.

文件类型过滤是目前所有的浏览器都不支持。但是我们设置了HTML 5接受属性所以一旦浏览器支持,它就会工作。

5. Multipart upload is only supported in Gecko and WebKit.

多部分上传仅支持在Gecko和WebKit。

关于Plupload的一些说明:

1) Plupload使用jQuery的组件做为选择文件和上传文件的队列组件。

2) Plupload使用Flash,Silverlight,HTML5,Gears,BrowserPlus、FileUpload上传文件技术引擎。

3) Plupload允许自定义使用Plupload核心API来进行选择文件与上传文件。

4) JavaScript用来激活文件选择对话框。此文件选择对话框是可以设置允许用户选择一个单独的文件或者是多个文件。 选择的的文件类型也是可以被限制的,因此用户只能选择指定的适当的文件,例如jgp;gif。

5)  Plupload允许对上传过程中的一些事件进行自定义,写上自己的处理方式。

6)  选定的文件的上传和它所在页面、表单是独立的。每个文件都是单独上传的,这就保证了服务端脚本能够在一个时间点更容易地处理单个文件。具体信息可以访问Plupload官方网站:http://www.plupload.com/

一: 下面就是利用Plupload 组件,让客户一次选择多个文件,然后将选择的文件上传到服务器的批量文件解决方案。

让我们先来看看客户端的界面效果图。(多选文件,批量上传,上传进度显示)

1) 显示界面:

图1

2) 进行多文件选择:

图2

3) 上传进度显示

图3

图4

二:具体的代码与操作步骤:

第一步,要进行下面的过程,必须先准备好Plupload组件。
1) Plupload:大家可以访问Plupload官方网站:http://www.plupload.com/,在这个网站上可以下载到组件与demo。

第二步,创建应用的目录结构,我这个示例的目录结构如图:
1.主要目录结构

2. 文件上传用到的js脚本文件。

3. jquery.ui.plupload目录中的文件,这个文件实际上就是界面中的显示信息。

第三步,前台部分准备客户操作的WEB界面,如下[WebUploadFileTest2.aspx、uploadFiles.ashx]

1) 前台客户端代码,其中WebUploadFileTest2.aspx的代码如下,WebUploadFileTest2.aspx.cs文件中只使用默认的代码,不用添加任何代码。
WebUploadFileTest2.aspx
Html代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebUploadFileTest2.aspx.cs" Inherits="WebApplication1.WebUploadFileTest2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

   <title>多文件上传</title>

   <!-- Load Queue widget CSS and jQuery -->

<style type="text/css">@import url(Scripts/jquery.ui.plupload/css/jquery.ui.plupload.css);</style>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/base/jquery-ui.css"/>

<!-- Third party script for BrowserPlus runtime (Google Gears included in Gears runtime now) -->

<script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>

<!-- Load plupload and all it's runtimes and finally the jQuery UI queue widget -->

<script type="text/javascript" src="Scripts/plupload.full.js"></script>

<script type="text/javascript" src="Scripts/jquery.ui.plupload/jquery.ui.plupload.js"></script>

<script type="text/javascript">

    // Convert divs to queue widgets when the DOM is ready

    $(function () {

        $("#uploader").plupload({

            // General settings

            runtimes: 'gears,flash,silverlight,browserplus,html5', // 这里是说用什么技术引擎

            url: 'uploadFiles.ashx', // 服务端上传路径

            max_file_size: '10mb', // 文件上传最大限制。

            chunk_size: '1mb', // 上传分块每块的大小,这个值小于服务器最大上传限制的值即可。

            unique_names: true, // 上传的文件名是否唯一

            // Resize images on clientside if we can

            //// 是否生成缩略图(仅对图片文件有效)

            resize: { width: 320, height: 240, quality: 90 },

            // Specify what files to browse for

            ////  这个数组是选择器,就是上传文件时限制的上传文件类型

            filters: [

{ title: "Image files", extensions: "jpg,gif,png" },

{ title: "Zip files", extensions: "zip,rar,7z" }

],

            // Flash settings

            // plupload.flash.swf 的所在路径

            flash_swf_url: 'Scripts/plupload.flash.swf',

            // Silverlight settings

            // silverlight所在路径

            silverlight_xap_url: 'Scripts/plupload.silverlight.xap'

        });

        // Client side form validation

        $('form').submit(function (e) {

            var uploader = $('#uploader').plupload('getUploader');

            // Files in queue upload them first

            if (uploader.files.length > 0) {

                // When all files are uploaded submit form

                uploader.bind('StateChanged', function () {

                    if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {

                        $('form')[0].submit();

                    }

                });

                uploader.start();

            } else

                alert('You must at least upload one file.');

            return false;

        });

    });

</script>

</head>

<body>

    <form id="form1" runat="server">

    <div>

     <h2>一次选择多个文件进行上传</h2>

    </div>

     <div id="uploader" style="width: 600px">

        <p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>

    </div>

    </form>

</body>

</html>

以上代码最后的显示结果如图:

图8.

2)后台服务器端代码:uploadFiles.ashx文件中使用默认的代码,不需要添加任何代码。uploadFiles.ashx.cs文件的代码如下:

    /// <summary>
    /// uploadFiles 的摘要说明
    /// </summary>
    public class uploadFiles : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.Write("Hello World");
            UploadFile(context);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        public void UploadFile(HttpContext context)
        {
            context.Response.CacheControl = "no-cache";
            string s_rpath = FileHelper.GetUploadPath();//@"E:\My Documents\Visual Studio 2008\WebSites\SWFUpload\demos\applicationdemo.net";

            string Datedir = DateTime.Now.ToString("yy-MM-dd");
            string updir = s_rpath + "\\" + Datedir;
            string extname = string.Empty;
            string fullname = string.Empty;
            string filename = string.Empty;
            if (context.Request.Files.Count > 0)
            {
                try
                {

                    for (int j = 0; j < context.Request.Files.Count; j++)
                    {

                        HttpPostedFile uploadFile = context.Request.Files[j];
                        int offset =Convert.ToInt32( context.Request["chunk"]); //当前分块
                        int total =Convert.ToInt32(context.Request["chunks"]);//总的分块数量
                        string name = context.Request["name"];
                        //文件没有分块
                        if (total == 1)
                        {

                            if (uploadFile.ContentLength > 0)
                            {
                                if (!Directory.Exists(updir))
                                {
                                    Directory.CreateDirectory(updir);
                                }
                                 extname = Path.GetExtension(uploadFile.FileName);
                                 fullname = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
                                 filename = uploadFile.FileName;

                                uploadFile.SaveAs(string.Format("{0}\\{1}", updir, filename));
                            }
                        }
                        else
                        {
                            //文件 分成多块上传
                            fullname = WriteTempFile(uploadFile, offset);
                            if (total-offset==1)
                            {
                                //如果是最后一个分块文件 ,则把文件从临时文件夹中移到上传文件 夹中
                                System.IO.FileInfo fi = new System.IO.FileInfo(fullname);
                                string oldFullName = string.Format("{0}\\{1}", updir, uploadFile.FileName);
                                FileInfo oldFi = new FileInfo(oldFullName);
                                if (oldFi.Exists)
                                {
                                    //文件名存在则删除旧文件
                                    oldFi.Delete();
                                }
                                fi.MoveTo(oldFullName);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    context.Response.Write("Message" + ex.ToString());
                }

            }
        }
        /// <summary>
        /// 保存临时文件
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="chunk"></param>
        /// <returns></returns>
        private string WriteTempFile(HttpPostedFile uploadFile, int chunk)
        {

            string tempDir = FileHelper.GetTempPath();
            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }
            string fullName = string.Format("{0}\\{1}.part", tempDir, uploadFile.FileName);
            if (chunk==0)
            {
                //如果是第一个分块,则直接保存
                uploadFile.SaveAs(fullName);
            }
            else
            {
                //如果是其他分块文件 ,则原来的分块文件,读取流,然后文件最后写入相应的字节
                FileStream fs = new FileStream(fullName, FileMode.Append);
                if (uploadFile.ContentLength>0)
                {
                int       FileLen = uploadFile.ContentLength;
   byte[] input = new byte[FileLen];

   // Initialize the stream.
   System.IO.Stream MyStream = uploadFile.InputStream;

   // Read the file into the byte array.
   MyStream.Read(input, 0, FileLen);

   fs.Write(input,0,FileLen);
   fs.Close();
                }
            }

            return fullName;
        }

    }

第四步:文件辅助类

/// <summary>
///FileHelper 的摘要说明
/// </summary>
public class FileHelper
{
    public FileHelper()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }
    /// <summary>
    /// 获取上传目录
    /// </summary>
    /// <returns></returns>
     public static string GetUploadPath()
        {
          string path = HttpContext.Current.Server.MapPath("~/");
          string dirname = GetDirName();
          string uploadDir = path + "\\" + dirname;
          CreateDir(uploadDir);
          return uploadDir;
        }
    /// <summary>
    /// 获取临时目录
    /// </summary>
    /// <returns></returns>
     public static string GetTempPath()
     {
         string path = HttpContext.Current.Server.MapPath("~/");
         string dirname = GetTempDirName();
         string uploadDir = path + "\\" + dirname;
         CreateDir(uploadDir);
         return uploadDir;
     }
        private static string GetDirName()
        {
            return System.Configuration.ConfigurationManager.AppSettings["uploaddir"];
        }
        private static string GetTempDirName()
        {
            return System.Configuration.ConfigurationManager.AppSettings["tempdir"];
        }
    public static void CreateDir(string path)
        {
                if (!System.IO.Directory.Exists(path))
                {
                    System.IO.Directory.CreateDirectory(path);
                }
        }
}

第五步,在进行上传之后,图片文件进行缩略图保存。如下图。

图 9

注释掉以下语句:    // resize: { width: 320, height: 240, quality: 90 }, 之后上传之后的图片,plupload组件将不在进行缩略。如下图。

图10

第六步:以上都是英文界面,可以添加中文语言包。代码如下。

<!-- Load Queue widget CSS and jQuery -->

<style type="text/css">@import url(Scripts/jquery.ui.plupload/css/jquery.ui.plupload.css);</style>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/themes/base/jquery-ui.css"/>

<!-- Third party script for BrowserPlus runtime (Google Gears included in Gears runtime now) -->

<script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>

<!-- Load plupload and all it's runtimes and finally the jQuery UI queue widget -->

<script type="text/javascript" src="Scripts/plupload.full.js"></script>

<script type="text/javascript" src="Scripts/i18n/zh-cn.js"></script> //这一句是重点,添加中文语言包文件 

<script type="text/javascript" src="Scripts/jquery.ui.plupload/jquery.ui.plupload.js"></script>

添加中文语言包之后的界面显示如下图:

上传错误信息:

demo文件 :批量文件上传示例

一共有两个文件 :WebUploadFileTest2.aspx示例是上文中给出的代码示例文件 。

WebUploadFileTest.aspx是另一个示例文件 。

 
分类: AspNetc#

WEB版一次选择多个文件进行批量上传(Plupload)的解决方案的更多相关文章

  1. WEB版一次选择多个文件进行批量上传(WebUploader)的解决方案

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  2. WEB版一次选择多个文件进行批量上传(swfupload)的解决方案

    说明:功能完全支持ie和firefox浏览器! 一般的WEB方式文件上传只能使用FileUpload控件进行一个文件一个文件的进行上传,就算是批量上传,也要把文件一个一个的添加到页面,无法如windo ...

  3. [Plugin] WEB版一次选择多个文件进行批量上传(swfupload)的解决方案

    URL:http://www.cnblogs.com/chillsrc/archive/2010/02/21/1670594.html 说明:功能完全支持ie和firefox浏览器! 一般的WEB方式 ...

  4. WEB版一次选择多个图片进行批量上传(WebUploader)的解决方案

    最近在学习百度的开源上传组件WebUploader,上一篇文章,学习了批量文件上传,今天学习一下批量图片上传,实际上与文件上传很类似,只是添加了图片显示功能,这个功能WebUploader组件中已经提 ...

  5. Linux svn一次增加多个文件并批量上传

    命令行下操作svn没有使用界面形式的TortoiseSVN直观,但是不管怎样,命令行下操作svn还是有它的有点,如果你碰到一次需要svn add许多个文件怎么办?下面的命令可以帮助你解决这个问题 一次 ...

  6. 【全网首创】修改 Ext.ux.UploadDialog.Dialog 源码支持多选添加文件,批量上传文件

    公司老框架的一个页面需要用到文件上传,本以为修改一个配置参数即可解决,百度一番发现都在说这个第三方插件不支持文件多选功能,还有各种各样缺点,暂且不讨论这些吧.先完成领导安排下来的任务. 任务一:支持多 ...

  7. B/S开发——文件夹的上传和下载

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  8. uploadify文件批量上传

    uploadify能够时间文件的批量上传,JS文件包下载地址,使用说明可以参考官网文档(http://www.uploadify.com/documentation/) 使用方法如下代码: $(&qu ...

  9. web自动化测试难点 滚动条操作、日期框处理、上传文件

    如何把页面滑到最低部? 一般来说,做web自动化测试时,不需要单独写代码,把页面滑到可见,因为click操作,只要是元素存在并且加载出来了,就可以点击到,无需另外写滑动元素的代码. 如果特殊情况需要滑 ...

随机推荐

  1. 数据结构Java实现06----中缀表达式转换为后缀表达式

    本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后 ...

  2. 第23章 SEH结构化异常处理(2)_编译器对系统SEH机制的封装

    23.2 编译器层面对系统SEH机制的封装 23.2.1 扩展的EXCEPTION_REGISTRATION级相关结构:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTIO ...

  3. 获取WIN10技术预览版

    说明 这是一款预发行软件 在进行商业发行之前,我们可能会对 Windows Technical Preview 进行大量修改. Microsoft 不对此处提供的信息作任何明示或默示的担保. 有些产品 ...

  4. iOS之block

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

  5. Android 界面排版的5种方式

    Android布局是应用界面开发的重要一环,在Android中,共有五种布局方式,分别是:FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对 ...

  6. 转载:关于 WebBrowser只对浏览器外应用程序以及在Internet Explorer 中以提升权限运行的应用程序启用

    我是根据很多大神写的博客,以及我自己在做项目的时候做的关于提升Silverlight 中WebBrowser 提升信任的问题的总结: 1)选中Silverlight主程序,右键“属性”---“Sliv ...

  7. android Camera 中如何修改缩放变焦参数

    如何修改 zoomRatio   修改过程:   1, 先找到 gZoomRatio 数组序列的值   Location: V:\project_code\project_name\ALPS.JB.M ...

  8. C语言 文件操作1--二进制文件与文本文件

    //写文件两种方式(文本文件和二进制文件) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h&g ...

  9. 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条

    不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...

  10. Android 动画之ScaleAnimation应用详解

    本节讲解ScaleAnimation 动画, ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, ...