C#实现多线程下载文件的方法
本文实例讲述了C#实现多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.IO; usingSystem.Threading; usingSystem.Net; namespaceWfpApp { publicclassMultiDownload { #region变量 privateint_threadNum;//线程数量 privatelong_fileSize;//文件大小 privatestring_fileUrl;//文件地址 privatestring_fileName;//文件名 privatestring_savePath;//保存路径 privateshort_threadCompleteNum;//线程完成数量 privatebool_isComplete;//是否完成 privatevolatileint_downloadSize;//当前下载大小(实时的) privateThread[]_thread;//线程数组 privateList<string>_tempFiles=newList<string>(); privateobjectlocker=newobject(); #endregion #region属性 ///<summary> ///文件名 ///</summary> publicstringFileName { get { return_fileName; } set { _fileName=value; } } ///<summary> ///文件大小 ///</summary> publiclongFileSize { get { return_fileSize; } } ///<summary> ///当前下载大小(实时的) ///</summary> publicintDownloadSize { get { return_downloadSize; } } ///<summary> ///是否完成 ///</summary> publicboolIsComplete { get { return_isComplete; } } ///<summary> ///线程数量 ///</summary> publicintThreadNum { get { return_threadNum; } } ///<summary> ///保存路径 ///</summary> publicstringSavePath { get { return_savePath; } set { _savePath=value; } } #endregion ///<summary> ///构造函数 ///</summary> ///<paramname="threahNum">线程数量</param> ///<paramname="fileUrl">文件Url路径</param> ///<paramname="savePath">本地保存路径</param> publicMultiDownload(intthreahNum,stringfileUrl,stringsavePath) { this._threadNum=threahNum; this._thread=newThread[threahNum]; this._fileUrl=fileUrl; this._savePath=savePath; } publicvoidStart() { HttpWebRequestrequest=(HttpWebRequest)WebRequest.Create(_fileUrl); HttpWebResponseresponse=(HttpWebResponse)request.GetResponse(); _fileSize=response.ContentLength; intsingelNum=(int)(_fileSize/_threadNum);//平均分配 intremainder=(int)(_fileSize%_threadNum);//获取剩余的 request.Abort(); response.Close(); for(inti=0;i<_threadNum;i++) { List<int>range=newList<int>(); range.Add(i*singelNum); if(remainder!=0&&(_threadNum-1)==i)//剩余的交给最后一个线程 range.Add(i*singelNum+singelNum+remainder-1); else range.Add(i*singelNum+singelNum-1); //下载指定位置的数据 int[]ran=newint[]{range[0],range[1]}; _thread[i]=newThread(newParameterizedThreadStart(Download)); _thread[i].Name=System.IO.Path.GetFileNameWithoutExtension(_fileUrl)+"_{0}".Replace("{0}",Convert.ToString(i+1)); _thread[i].Start(ran); } } privatevoidDownload(objectobj) { StreamhttpFileStream=null,localFileStram=null; try { int[]ran=objasint[]; stringtmpFileBlock=System.IO.Path.GetTempPath()+Thread.CurrentThread.Name+".tmp"; _tempFiles.Add(tmpFileBlock); HttpWebRequesthttprequest=(HttpWebRequest)WebRequest.Create(_fileUrl); httprequest.AddRange(ran[0],ran[1]); HttpWebResponsehttpresponse=(HttpWebResponse)httprequest.GetResponse(); httpFileStream=httpresponse.GetResponseStream(); localFileStram=newFileStream(tmpFileBlock,FileMode.Create); byte[]by=newbyte[5000]; intgetByteSize=httpFileStream.Read(by,0,(int)by.Length);//Read方法将返回读入by变量中的总字节数 while(getByteSize>0) { Thread.Sleep(20); lock(locker)_downloadSize+=getByteSize; localFileStram.Write(by,0,getByteSize); getByteSize=httpFileStream.Read(by,0,(int)by.Length); } lock(locker)_threadCompleteNum++; } catch(Exceptionex) { thrownewException(ex.Message.ToString()); } finally { if(httpFileStream!=null)httpFileStream.Dispose(); if(localFileStram!=null)localFileStram.Dispose(); } if(_threadCompleteNum==_threadNum) { Complete(); _isComplete=true; } } ///<summary> ///下载完成后合并文件块 ///</summary> privatevoidComplete() { StreammergeFile=newFileStream(@_savePath,FileMode.Create); BinaryWriterAddWriter=newBinaryWriter(mergeFile); foreach(stringfilein_tempFiles) { using(FileStreamfs=newFileStream(file,FileMode.Open)) { BinaryReaderTempReader=newBinaryReader(fs); AddWriter.Write(TempReader.ReadBytes((int)fs.Length)); TempReader.Close(); } File.Delete(file); } AddWriter.Close(); } } }
调用:
stringhttpUrl=@"http://172.28.98.96/fdimsservice/2.rar"; stringsaveUrl=System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"//"+System.IO.Path.GetFileName(httpUrl); intthreadNumber=5; MultiDownloadmd=newMultiDownload(threadNumber,httpUrl,saveUrl); md.Start();
希望本文所述对大家的C#程序设计有所帮助。