Beispiel #1
0
        private List <object> ReadConfig(string configPath)
        {
            List <object> list = new List <object>();
            string        str  = File.ReadAllText(configPath);

            byte[] buffer = Convert.FromBase64String(str);
            str = System.Text.Encoding.UTF8.GetString(buffer);
            lock (locker)
            {
                string[] split        = str.Split(';');
                long     downloadSize = Convert.ToInt64(split[0]);
                long     totalSize    = Convert.ToInt64(split[1]);
                Queue <ThreadDownloadInfo> downQueue = new Queue <ThreadDownloadInfo>(); //下载信息队列
                foreach (Match match in Regex.Matches(str, "\\((\\d+),(\\d+)\\);"))
                {
                    ThreadDownloadInfo downInfo = new ThreadDownloadInfo();
                    downInfo.startLength = Convert.ToInt64(match.Groups[1].Value);
                    downInfo.length      = Convert.ToInt32(match.Groups[2].Value);
                    downQueue.Enqueue(downInfo);
                }

                list.Add(downloadSize);
                list.Add(totalSize);
                list.Add(downQueue);
            }

            return(list);
        }
Beispiel #2
0
        private void ThreadWork(string url, FileStream fs, Queue <ThreadDownloadInfo> downQueue)
        {
            mre.WaitOne();
            if (cancelTokenSource.IsCancellationRequested)
            {
                return;
            }

            ThreadDownloadInfo downInfo = null;

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

            HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);

            request.AddRange(downInfo.startLength); //设置Range值
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            System.IO.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)
                {
                    this.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);
        }
Beispiel #3
0
        public async void StartDownload(DownloadInfo info)
        {
            this.downloadSize = 0;
            if (String.IsNullOrEmpty(info.DownLoadUrl))
            {
                throw new Exception("下载地址不能为空!");
            }
            if (info.DownLoadUrl.ToLower().StartsWith("http://"))
            {
                await Task.Run(() =>
                {
                    bool isError = false;
                    try
                    {
                        long totalSize          = 0;
                        long threadInitedLength = 0; //分配线程任务的下载量

                        #region 获取文件信息
                        //打开网络连接
                        System.Net.HttpWebRequest initRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(info.DownLoadUrl);
                        System.Net.WebResponse initResponse   = initRequest.GetResponse();
                        FileMessage fileMsg = 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";
                        List <object> initInfo = null;
                        if (File.Exists(configPath) && (info.IsNew == false))
                        {
                            initInfo     = this.ReadConfig(configPath);
                            downloadSize = (long)initInfo[0];
                            totalSize    = (long)initInfo[1];
                        }
                        #endregion

                        #region  计算速度
                        //Stopwatch MyStopWatch = new Stopwatch();
                        long lastDownloadSize    = 0;     //上次下载量
                        bool isSendCompleteEvent = false; //是否完成
                        Timer timer = new Timer(new TimerCallback((o) =>
                        {
                            if (!isSendCompleteEvent && !isError)
                            {
                                DownloadEvent e = new DownloadEvent();
                                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 = (Queue <ThreadDownloadInfo>)initInfo[2];
                        }

                        System.IO.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();
                            //保存配置文件
                            SaveConfig(configPath, downloadSize, totalSize, downQueue);
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        isError = true;
                        if (ErrorMakedEvent != null)
                        {
                            ErrorMakedEvent(ex.Message);
                        }
                    }
                });
            }
        }