程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 多線程下載文件單元(Helpr)

C# 多線程下載文件單元(Helpr)

編輯:C#入門知識

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
using System.Net; 
using System.Threading; 
 
namespace Update 

    class MultiThreadDownLoad 
    { 
        #region 變量 
        private int _threadNum;             //線程數量 
        private long _fileSize;             //文件大小 
        private string _extName;            //文件擴展名 
        private string _fileUrl;            //文件地址 
        private string _fileName;           //文件名 
        private string _savePath;           //保存路徑 
        private short _threadCompleteNum;   //線程完成數量 
        private bool _isComplete;           //是否完成 
        private volatile int _downloadSize; //當前下載大小(實時的) 
        public Thread[] _thread;           //線程數組 
        private List<string> _tempFiles = new List<string>(); 
        private List<List<int>> readft = new List<List<int>>();//存放每個線程讀取的起始和結束位置 
        private object locker = new object(); 
        #endregion 
 
        #region 屬性 
        public string FileName 
        { 
            get 
            { 
                return _fileName; 
            } 
            set 
            { 
                _fileName = value; 
            } 
        } 
 
        public long FileSize 
        { 
            get 
            { 
                return _fileSize; 
            } 
        } 
 
        public int DownloadSize 
        { 
            get 
            { 
                return _downloadSize; 
            } 
        } 
 
        public bool IsComplete 
        { 
            get 
            { 
                return _isComplete; 
            } 
            set 
            { 
                _isComplete = value; 
            } 
        } 
 
        public int ThreadNum 
        { 
            get 
            { 
                return _threadNum; 
            } 
        } 
 
        public string SavePath 
        { 
            get 
            { 
                return _savePath; 
            } 
            set 
            { 
                _savePath = value; 
            } 
        } 
        #endregion 
 
        /// <summary> 
        /// 構造函數 
        /// </summary> 
        /// <param name="threahNum">線程數量</param> 
        /// <param name="fileUrl">文件Url路徑</param> 
        /// <param name="savePath">本地保存路徑</param> 
        public MultiThreadDownLoad(int threahNum, string fileUrl, string savePath) 
        { 
            this._threadNum = threahNum; 
            this._thread = new Thread[threahNum]; 
            this._fileUrl = fileUrl; 
            this._savePath = savePath; 
        } 
 
        //_serverUrl為http://xxx.xx/xx.dll形式 
        //_localFile為\\Program File\xx.dll形式 PS:終端路徑 
         
        public void Start() 
        { 
             
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_fileUrl); 
            HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
            _extName = response.ResponseUri.ToString().Substring(response.ResponseUri.ToString().LastIndexOf('.'));//獲取真實擴展名 
            _fileSize = response.ContentLength; 
 
            int singelNum = (int)(_fileSize / _threadNum);      //平均分配 
            int remainder = (int)(_fileSize % _threadNum);      //獲取剩余的 
            request.Abort(); 
            response.Close(); 
            for (int i = 0; i < _threadNum; i++) 
            { 
                List<int> range = new List<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); 
                readft.Add(range); 
                _thread[i] = new Thread(new ThreadStart(Download)); 
                _thread[i].Name = i.ToString(); 
                _thread[i].Start(); 
            } 
        } 
 
        private void Download() 
        { 
            Stream httpFileStream = null, localFileStram = null; 
            try 
            { 
                string tmpFileBlock = String.Format(@"{0}\{1}_{2}.dat",_savePath,FileName ,Thread.CurrentThread.Name); 
                _tempFiles.Add(tmpFileBlock); 
                HttpWebRequest httprequest = (HttpWebRequest)HttpWebRequest.Create(_fileUrl); 
                httprequest.AddRange(readft[Convert.ToInt32(Thread.CurrentThread.Name)][0], readft[Convert.ToInt32(Thread.CurrentThread.Name)][1]); 
                HttpWebResponse httpresponse = (HttpWebResponse)httprequest.GetResponse(); 
                httpFileStream = httpresponse.GetResponseStream(); 
                localFileStram = new FileStream(tmpFileBlock, FileMode.Create); 
                byte[] by = new byte[1024]; 
                int getByteSize = httpFileStream.Read(by, 0, 1024);           //Read方法將返回讀入by變量中的總字節數 
                while (getByteSize > 0) 
                { 
                    Thread.Sleep(20); 
                    lock (locker) _downloadSize += getByteSize; 
                    localFileStram.Write(by, 0, getByteSize); 
                    getByteSize = httpFileStream.Read(by, 0, 1024); 
                } 
                lock (locker) 
                    _threadCompleteNum++; 
                 
            } 
            catch (Exception ex) 
            { 
                throw new Exception(ex.Message.ToString()); 
            } 
            finally 
            { 
                if (httpFileStream != null) httpFileStream.Close(); 
                if (localFileStram != null) localFileStram.Close(); 
            } 
            if (_threadCompleteNum == _threadNum) 
            { 
                Complete(); 
                _isComplete = true; 
            } 
        } 
 
        /// <summary> 
        /// 下載完成後合並文件塊 
        /// </summary> 
        private void Complete() 
        { 
            Stream mergeFile=null; 
            BinaryWriter AddWriter=null; 
            try 
            { 
                mergeFile = new FileStream(String.Format(@"{0}\{1}", _savePath, FileName), FileMode.Create); 
                AddWriter = new BinaryWriter(mergeFile); 
                foreach (string file in _tempFiles) 
                { 
                    using (FileStream fs = new FileStream(file, FileMode.Open)) 
                    { 
                        BinaryReader TempReader = new BinaryReader(fs); 
                        AddWriter.Write(TempReader.ReadBytes((int)fs.Length)); 
                        TempReader.Close(); 
                    } 
                    File.Delete(file); 
                } 
            } 
            catch (Exception ex) 
            { 
                throw new Exception(ex.Message); 
            } 
            finally 
            { 
                AddWriter.Close(); 
                mergeFile.Close(); 
            } 
 
        } 
    } 


摘自 #Define

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved