⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadfile.cs

📁 断点续传,下载DEMO 是VS2008下写的,我收集的在这里共享给大家
💻 CS
字号:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Security;
using System.Threading;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Data;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;

namespace Cblang.HttpDownload
{
    /// <summary>
    /// Class for download thread
    /// </summary>
    public class DownloadFile
    {
        private DownloadFileInfo _fileInfo;
        private Thread[] _subThreads;
        private int _threadFinishedCount;
        private int _threadNumber;
        private bool _overrideFile = false; //不覆盖同名文件
        private bool _isStopped = true;
        /// <summary>
        /// 接收数据委托
        /// </summary>
        public EventHandler<DownLoadEventArgs> DataReceived;

        /// <summary>
        /// 下载完成事件
        /// </summary>
        public event EventHandler Finished;
        /// <summary>
        /// 线程完成事件
        /// </summary>
        public event EventHandler ThreadFinished;
    
        /// <summary>
        /// 下载的文件信息
        /// </summary>
        public DownloadFileInfo FileInfo
        {
            get { return _fileInfo; }
        }

        /// <summary>
        /// 下载后是否翻盖同名文件
        /// </summary>
        public bool OverrdeFile
        {
            get { return _overrideFile; }
            set { _overrideFile = value; }
        }

       /// <summary>
       /// 新建下载..
       /// </summary>
       /// <param name="requestURL">要下载文件的URL</param>
       /// <param name="fileName">本地文件名</param>
        /// <param name="threadNumber">使用的线程数</param>
        public DownloadFile(string requestURL, string fileName, int threadNumber)
        {
            // Create download file info
            _fileInfo = new DownloadFileInfo(requestURL, fileName);
            if (threadNumber <= 0)
            {
                threadNumber = 5;//Defualt value
            }
            this._threadNumber = threadNumber;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        public DownloadFile(string  fileName)
        {
            DownloadFileInfo fileInfo = CreateDownloadFile(fileName);
            _fileInfo = fileInfo;
            this._threadNumber = _fileInfo.Packets.Length;
        }

        //public DownloadFile(DownloadFileInfo fileInfo)
        //{
        //    _fileInfo = fileInfo;
        //    this.threadNumber = _fileInfo.Packets.Length;
        //}

        /// <summary>
        /// Start to download
        /// </summary>
        /// 
        public void Start()
        {
            if (_isStopped)
            {
                _isStopped = false;
                _threadFinishedCount = 0;
                if (_fileInfo.Packets == null)
                {
                    InitFileDownInfo();
                }
                StartSubThreads();
            }
        }

        /// <summary>
        /// Check url to get download file info
        /// </summary>
        /// <returns></returns>
        private void InitFileDownInfo()
        {
            //Create request
            HttpWebRequest hwrq = (HttpWebRequest)WebRequest.Create(_fileInfo.RequestURL);
            using (HttpWebResponse hwrp = (HttpWebResponse)hwrq.GetResponse())
            {
                //Get file size info
                long L = hwrp.ContentLength;
                L = ((L == -1) || (L > 0x7fffffff)) ? ((long)0x7fffffff) : L;

                //Check whether this url is supported to be multi-threads download
                bool blnMulti = (hwrp.Headers["Accept-Ranges"] != null && hwrp.Headers["Accept-Ranges"] == "bytes");
                if (!blnMulti)
                {
                    _threadNumber = 1;
                }
                _fileInfo.InitPackets((int)L, _threadNumber);
            }
        }


        /// <summary>
        /// Start sub-threads to download file
        /// </summary>
        private void StartSubThreads()
        {
            _subThreads = new Thread[this._threadNumber];
            for (int i = 0; i < _threadNumber; i++)
            {
                Packet packet = _fileInfo.Packets[i];
                if (packet.LoadSize + packet.From <= packet.To)
                {
                    _subThreads[i] = new Thread(new ThreadStart(Download));
                    _subThreads[i].Name = i.ToString();
                    _subThreads[i].Start();
                }
                else
                {
                    _threadFinishedCount++;
                    Debug.WriteLine(string.Format("Thread NO:{0} sends finish-info!", i.ToString()));
                }
            }
        }

        /// <summary>
        /// Function for sub-thread
        /// </summary>
        private void Download()
        {
            int threadNO = int.Parse(System.Threading.Thread.CurrentThread.Name);
            Packet packet = _fileInfo.Packets[threadNO];
            //if (packet.LoadSize + packet.From > packet.To)
            //{
            //    Debug.WriteLine(string.Format("Thread NO:{0} sends finish-info!", threadNO));
            //    EventHandler finishHandle = ThreadFinished;
            //    if (finishHandle != null)
            //    {
            //        finishHandle(this, EventArgs.Empty);
            //    }
            //    return;
            //}
            Debug.WriteLine(string.Format("Thread NO:{0} begins to download!", threadNO));
            // Creat request by url 
            HttpWebRequest hwrq = (HttpWebRequest)WebRequest.Create(new Uri(_fileInfo.RequestURL));

            // Go to download position
            hwrq.AddRange(packet.LoadSize + packet.From, packet.To);
            // Get response from request
            using (HttpWebResponse hwrp = (HttpWebResponse)hwrq.GetResponse())
            {
                // download and write data from 
                Debug.WriteLine(string.Format("Thread NO:{0} call function named DownloadData!", threadNO));
                using (Stream sReader = hwrp.GetResponseStream())
                {
                    DownloadData(sReader, threadNO, packet);
                }
            }
        }

        //Download data through web request
        private void DownloadData(Stream sReader, int threadNO, Packet packet)
        {
            using (FileStream sw = new FileStream(_fileInfo.FileName + DownloadFileInfo.FilenameExt, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
            {
                int readCount = 0;
                sw.Position = packet.From + packet.LoadSize;
                int position = packet.From + packet.LoadSize;
                while (!_isStopped && position <= packet.To)
                {
                    Debug.WriteLine(string.Format("Thread NO:{0} reads data!", threadNO));

                    // Read data
                    readCount = sReader.Read(packet.Buffer, 0, Packet.BUFFER_SIZE);
                    if (readCount <= 0)
                    {
                        break;
                    }
                    Debug.WriteLine(string.Format("Thread NO:{0} writes data!", threadNO));
                    // Write data
                    // sw.Position = packet.LoadSize + packet.From;
                    sw.Write(packet.Buffer, 0, readCount);
                    sw.Flush();
                    packet.LoadSize += readCount;
                    _fileInfo.BlockLeftSize += readCount;

                    Debug.WriteLine(string.Format("Thread NO:{0} writes {1} data!", threadNO, readCount));

                    // Call back
                    EventHandler<DownLoadEventArgs> receivedHandler = DataReceived;
                    if (receivedHandler != null)
                    {
                        Debug.WriteLine(string.Format("Thread NO:{0} send callback info!", threadNO));
                        receivedHandler(this, new DownLoadEventArgs(
                            _fileInfo, position, readCount, threadNO));
                    }

                    position += readCount;
                }
            }
            if (_isStopped)
            {
                return;
            }
            Debug.WriteLine(string.Format("Thread NO:{0} sends finish-info!", threadNO));

            EventHandler finishHandle = ThreadFinished;
            if (finishHandle != null)
            {
                finishHandle(this, EventArgs.Empty);
            }
            _threadFinishedCount++;
            if (_threadFinishedCount == _subThreads.Length)
            {
                DownloadFinished();
            }
        }

        /// <summary>
        /// Thread download finished
        /// </summary>
        private void DownloadFinished()
        {
            // Some download thread finished
            if (_overrideFile && File.Exists(_fileInfo.FileName))
            {
                File.Delete(_fileInfo.FileName);
            }
            string filename = GetNewFilename(_fileInfo.FileName);
            File.Move(_fileInfo.FileName + DownloadFileInfo.FilenameExt, filename);

            EventHandler handler = Finished;
            if (handler != null)
            {
                handler(_fileInfo, EventArgs.Empty);
            }
        }

        /// <summary>
        /// 停止下载
        /// </summary>
        public void Stop()
        {
            if (!_isStopped)
            {
                _isStopped = true;
                for (int i = 0; i < _subThreads.Length; i++)
                {
                    if ((_subThreads[i] != null) && (_subThreads[i].ThreadState == System.Threading.ThreadState.Running))
                    {
                        _subThreads[i].Join(10);
                    }
                    Debug.WriteLine(string.Format("Thread NO:{0} is stopped!", i));
                }
                string name = MD5Helper.MD5Encrypt(_fileInfo.RequestURL);
                SaveFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name));
            }
        }

        /// <summary>
        /// 保存下载状态到文件
        /// </summary>
        /// <param name="fileName"></param>
        private void SaveFile(string fileName)
        {
            BinaryFormatter serializer = new BinaryFormatter();
            using (System.IO.MemoryStream memStream = new System.IO.MemoryStream())
            {
                serializer.Serialize(memStream, _fileInfo);
                using (FileStream sw = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write))
                {
                    memStream.WriteTo(sw);
                }
            }
        }

        /// <summary>
        /// 载入下载日志文件...
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static DownloadFileInfo CreateDownloadFile(string fileName)
        {
            using (FileStream sw = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                byte[] buffer = new byte[sw.Length];
                sw.Read(buffer, 0, buffer.Length);
                using (System.IO.MemoryStream memStream = new System.IO.MemoryStream(buffer))
                {
                    BinaryFormatter deserializer = new BinaryFormatter();
                    return (DownloadFileInfo)(deserializer.Deserialize(memStream));
                }
            }
        }

        /// <summary>
        /// 得到不重复的文件名
        /// </summary>
        /// <returns></returns>
        public static string GetNewFilename(string filename)
        {
            if (File.Exists(filename))
            {
                string newname = filename;
                int i = 0;
                int lastPoint = filename.LastIndexOf('.');
                do
                {
                    i++;
                    if (lastPoint < 1)
                    {
                        newname = filename + "(" + i + ")";
                    }
                    else
                    {
                        newname = filename.Substring(0, lastPoint) + "(" + i + ")" + filename.Substring(lastPoint);
                    }
                }
                while (File.Exists(newname));
                return newname;
            }
            else
            {
                return filename;
            }
        }

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -