Ejemplo n.º 1
0
        /// <summary>
        /// 保存文件下载的配置信息,包括总字节数、已下载字节数、下载队列信息
        /// </summary>
        /// <param name="configFile"></param>
        /// <param name="downloadSize"></param>
        /// <param name="totalSize"></param>
        /// <param name="downloadQueue"></param>
        public static void SaveConfig(string configFile, long downloadSize, long totalSize, Queue <ThreadDownloadInfo> downloadQueue)
        {
            var config = new FileDownloadConfig()
            {
                DownloadSize  = downloadSize,
                TotalSize     = totalSize,
                DownloadQueue = downloadQueue
            };

            Utils.WriteObjectToDisk(configFile, config);
        }
Ejemplo 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);
                }
            });
        }