Exemplo n.º 1
0
        private void ThreadWork(string url, FileStream fs, Queue <ThreadDownloadInfo> downQueue)
        {
            mre.WaitOne();
            if (cancelTokenSource.IsCancellationRequested)
            {
                return;
            }

            Monitor.Enter(downQueue);
            if (downQueue.Count == 0)
            {
                return;
            }
            ThreadDownloadInfo downInfo = downQueue.Dequeue();

            Monitor.Exit(downQueue);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.AddRange(downInfo.StartLength); //设置Range值
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream          ns       = response.GetResponseStream();

            byte[] nbytes    = new byte[DOWNLOAD_BUFFER_SIZE];
            int    temp      = 0;
            int    nReadSize = 0;

            byte[] buffer = new byte[downInfo.Length]; //文件写入缓冲
            nReadSize = ns.Read(nbytes, 0, Math.Min(DOWNLOAD_BUFFER_SIZE, downInfo.Length));
            while (temp < downInfo.Length)
            {
                mre.WaitOne();
                Buffer.BlockCopy(nbytes, 0, buffer, temp, nReadSize);
                lock (locker)
                {
                    downloadSize += nReadSize;
                }
                temp     += nReadSize;
                nReadSize = ns.Read(nbytes, 0, Math.Min(DOWNLOAD_BUFFER_SIZE, downInfo.Length - temp));
            }

            lock (locker)
            {
                fs.Seek(downInfo.StartLength, SeekOrigin.Begin);
                fs.Write(buffer, 0, buffer.Length);
            }

            ns.Close();
            ThreadWork(url, fs, downQueue);
        }
Exemplo n.º 2
0
        public async void StartDownload(FileDownloadInfo info)
        {
            if (string.IsNullOrEmpty(info.DownLoadUrl))
            {
                throw new Exception("下载地址不能为空!");
            }
            if (!info.DownLoadUrl.ToLower().StartsWith("http://") || !info.DownLoadUrl.ToLower().StartsWith("https://"))
            {
                throw new Exception("非法的下载地址!");
            }

            downloadSize = 0;
            await Task.Run(() =>
            {
                try
                {
                    long totalSize          = 0;
                    long threadInitedLength = 0; //分配线程任务的下载量

                    #region 获取文件信息
                    //打开网络连接
                    HttpWebRequest initRequest = (HttpWebRequest)WebRequest.Create(info.DownLoadUrl);
                    WebResponse initResponse   = initRequest.GetResponse();
                    FileInfo fileMsg           = FileInfo.GetFileMessage(initResponse);
                    totalSize = fileMsg.Length;
                    if ((!string.IsNullOrEmpty(fileMsg.FileName)) && info.LocalSaveFolder != null)
                    {
                        info.SavePath = Path.Combine(info.LocalSaveFolder, fileMsg.FileName);
                    }
                    //ReaderWriterLock readWriteLock = new ReaderWriterLock();
                    #endregion

                    #region 读取配置文件
                    string configPath           = info.SavePath.Substring(0, info.SavePath.LastIndexOf(".")) + ".cfg";
                    FileDownloadConfig initInfo = null;
                    if (File.Exists(configPath) && (info.IsNew == false))
                    {
                        initInfo     = FileDownloadConfig.ReadConfig(configPath);
                        downloadSize = (long)initInfo.DownloadSize;
                        totalSize    = (long)initInfo.TotalSize;
                    }
                    #endregion

                    #region  计算速度
                    //Stopwatch MyStopWatch = new Stopwatch();
                    long lastDownloadSize    = 0;     //上次下载量
                    bool isSendCompleteEvent = false; //是否完成
                    Timer timer = new Timer(new TimerCallback((o) =>
                    {
                        if (!isSendCompleteEvent)
                        {
                            FileDownloadEvent e = new FileDownloadEvent();
                            e.DownloadSize      = downloadSize;
                            e.TotalSize         = totalSize;
                            if (totalSize > 0 && downloadSize == totalSize)
                            {
                                e.Speed             = 0;
                                isSendCompleteEvent = true;
                                eventFinished.Set();
                            }
                            else
                            {
                                e.Speed          = downloadSize - lastDownloadSize;
                                lastDownloadSize = downloadSize; //更新上次下载量
                            }

                            DownloadEvent(e);
                        }
                    }), null, 0, 1000);
                    #endregion

                    string tempPath = info.SavePath.Substring(0, info.SavePath.LastIndexOf(".")) + ".dat";

                    #region 多线程下载
                    //分配下载队列
                    Queue <ThreadDownloadInfo> downQueue = null;
                    if (initInfo == null || info.IsNew)
                    {
                        downQueue = new Queue <ThreadDownloadInfo>(); //下载信息队列
                        while (threadInitedLength < totalSize)
                        {
                            ThreadDownloadInfo downInfo = new ThreadDownloadInfo();
                            downInfo.StartLength        = threadInitedLength;
                            downInfo.Length             = (int)Math.Min(Math.Min(THREAD_BUFFER_SIZE, totalSize - threadInitedLength), totalSize / info.ThreadCount); //下载量
                            downQueue.Enqueue(downInfo);
                            threadInitedLength += downInfo.Length;
                        }
                    }
                    else
                    {
                        downQueue = initInfo.DownloadQueue;
                    }

                    FileStream fs = new FileStream(tempPath, FileMode.OpenOrCreate);
                    fs.SetLength(totalSize);
                    int threads = info.ThreadCount;

                    for (int i = 0; i < info.ThreadCount; i++)
                    {
                        ThreadPool.QueueUserWorkItem((state) =>
                        {
                            ThreadWork(info.DownLoadUrl, fs, downQueue);
                            if (Interlocked.Decrement(ref threads) == 0)
                            {
                                (state as AutoResetEvent).Set();
                            }
                        }, eventFinished);
                    }

                    //等待所有线程完成
                    eventFinished.WaitOne();
                    if (fs != null)
                    {
                        fs.Close();
                    }
                    fs = null;
                    if (File.Exists(info.SavePath))
                    {
                        File.Delete(info.SavePath);
                    }

                    if (downloadSize == totalSize)
                    {
                        File.Move(tempPath, info.SavePath);
                        File.Delete(configPath);
                    }

                    if (cancelTokenSource.IsCancellationRequested && StopEvent != null)
                    {
                        StopEvent();
                        //保存配置文件
                        FileDownloadConfig.SaveConfig(configPath, downloadSize, totalSize, downQueue);
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    ErrorMakedEvent?.Invoke(ex.Message);
                }
            });
        }