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環境下。

具體的大家可以看源代碼,有什么大家改進交流。

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


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM