zoukankan      html  css  js  c++  java
  • silverlight多文件断点续传

          最近在做silverlight项目的时候经常性会遇到文件上传,看到163邮箱的断点续传,感觉用户体验真的很好,所有花了点时间研究了一下silverlight的断点续传功能。

          在博客园中找了一下没有这样的功能,后来看到代震军BLOG的博客中有一篇DiscuzNT使用Silverlight进行多文件上传 ,能上传多文件,可是没有实现断点续传,就自己动手修改了一下代码,实现简单的暂停后在续传功能,如果想做成如163邮箱那样的下次登录后还能在续传,就需要保存当时暂停的状态。首先感谢这些大牛们的技术支持和无私的代码奉献,好了,下面谈谈对代码的理解和更改。

      在里面利用的是依赖属性的状态改变来时时更新一些数据,如已上传的文件大小,以及文件上传的状态等,由于代码很多,挑选部分类似的代码如下,后面将源代码公布。

           /// <summary>
    /// 当前已上传的字节数(这里与FileCollection中的同名属性意义不同,FileCollection中的是已上传的所有文件的字节总数)
    /// </summary>
    public double BytesUploaded
    {
    get { return _bytesUploaded; }
    set
    {
    _bytesUploaded = value;

    NotifyPropertyChanged("BytesUploaded");

    Percentage = (int)((value * 100) / _fileStream.Length);

    }
    }
    #region INotifyPropertyChanged Members

    private void NotifyPropertyChanged(string prop)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    还有文件的上传时采用分块处理的,选择一块 byte[] buffer = new byte[4 * 4096]大小的内存,将文件分成N块如此大小的文件,在循环上传至最终完成。

    此代码在FileUploader.cs中,这一块是最重要的,如下所示,

    /// <summary>
    /// 上传文件
    /// </summary>
    private void UploadAdvanced()
    {

    byte[] buffer = new byte[4 * 4096];
    int bytesRead = _file.FileStream.Read(buffer, 0, buffer.Length);

    //文件是否上传完毕?
    if (bytesRead != 0)
    {
    _dataSent += bytesRead;

    if (_dataSent == _dataLength)
    _lastChunk = true;//是否是最后一块数据,这样WCF会在服务端根据该信息来决定是否对临时文件重命名

    //上传当前数据块
    _client.StoreFileAdvancedAsync(_file.FileName, buffer, bytesRead, _initParams, _firstChunk, _lastChunk);

    //在第一条消息之后一直为false
    _firstChunk = false;

    //通知上传进度修改
    OnProgressChanged();
    }
    else
    {
    //当上传完毕后
    _file.FileStream.Dispose();
    _file.FileStream.Close();

    _client.ChannelFactory.Close();
    }
    }

    再就是在上传的过程中需要一直判断文件是否被删除、完成或者中断,在FileUploader.cs中需要关注这段代码,

    void _client_StoreFileAdvancedCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
    //检查WEB服务是否存在错误
    if (e.Error != null)
    {
    //当错误时放弃上传
    _file.State = Constants.FileStates.Error;
    }
    else
    {
    //如果文件未取消上传并且没有的话,则继续上传
    if (!_file.IsDeleted && !_file.IsStop)
    UploadAdvanced();
    }
    }

    其中需要限制文件大小,以及同时上传的文件数量需要关注mpost.SilverlightMultiFileUploadTestPage.aspx中的InitParameters参数,以前的也可以在配置文件中配置,如果要改成配置文件的形式可以更改代码Page.xaml.cs中的代码。

    /// <summary>
    /// 加载配置参数 then from .Config file
    /// </summary>
    /// <param name="initParams"></param>
    private void LoadConfiguration(IDictionary<string, string> initParams)
    {
    string tryTest = string.Empty;

    //加载定制配置信息串
    if (initParams.ContainsKey("CustomParam") && !string.IsNullOrEmpty(initParams["CustomParam"]))
    _customParams = initParams["CustomParam"];

    if (initParams.ContainsKey("MaxUploads") && !string.IsNullOrEmpty(initParams["MaxUploads"]))
    {
    int.TryParse(initParams["MaxUploads"], out _maxUpload);
    }

    if (initParams.ContainsKey("MaxFileSizeKB") && !string.IsNullOrEmpty(initParams["MaxFileSizeKB"]))
    {
    if (int.TryParse(initParams["MaxFileSizeKB"], out _maxFileSize))
    _maxFileSize = _maxFileSize * 1024;
    }

    if (initParams.ContainsKey("FileFilter") && !string.IsNullOrEmpty(initParams["FileFilter"]))
    _fileFilter = initParams["FileFilter"];



    //从配置文件中获取相关信息
    if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["MaxFileSizeKB"]))
    {
    if (int.TryParse(ConfigurationManager.AppSettings["MaxFileSizeKB"], out _maxFileSize))
    _maxFileSize = _maxFileSize * 1024;
    }


    if(!string.IsNullOrEmpty(ConfigurationManager.AppSettings["MaxUploads"]))
    int.TryParse(ConfigurationManager.AppSettings["MaxUploads"], out _maxUpload);

    if(!string.IsNullOrEmpty( ConfigurationManager.AppSettings["FileFilter"]))
    _fileFilter = ConfigurationManager.AppSettings["FileFilter"];

    }


    其中还有其他的一些读者可以自己看代码调试运行试试,下面是运行的截图,环境是vs2010、silverlight4.0环境下。

    具体的大家可以看源代码,有什么大家改进交流。

    https://files.cnblogs.com/huangyuanfengxue/SilverlightMultiFileUploader.rar


     

  • 相关阅读:
    gridview 列排序问题
    asp.net中session丢失原因分析
    网页flash挡住了TQ的解决办法
    php正确率比较高的安装教程
    PHP5+APACHE2.2配置
    HTML5: HTML5 网站设计作品欣赏
    ASP.NET开源CMS汇总
    ASP.NET:页面传值的几种方式
    Access:数据库操作常见错误
    observer pattern
  • 原文地址:https://www.cnblogs.com/huangyuanfengxue/p/2324008.html
Copyright © 2011-2022 走看看