Пример #1
0
 /// <summary>
 /// 下载模组
 /// </summary>
 public void DownloadMod(DownloadStatus status)
 {
     DownloadModPrivate(status, 1);
 }
Пример #2
0
        //内部方法,用于下载失败时递归重试
        private void DownloadModPrivate(DownloadStatus status, int tryTime)
        {
            //检查下载失败
            if (tryTime > TryTime)
            {
                DownFailed?.Invoke(this, status);
                return;
            }

            string urlStr = string.Format(BASE_DOWNLOAD_URL, status.ProjectId, status.FileId);

            //检查网址正确性
            if (!Uri.TryCreate(urlStr, UriKind.Absolute, out Uri url))
            {
                throw new FormatException("Url格式错误");
            }

            var             req = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse rep;

            //超时检查
            try
            {
                rep = (HttpWebResponse)req.GetResponse();
            }
            catch (WebException)
            {
                //超时重试
                DownloadModPrivate(status, tryTime + 1);
                return;
            }


            //文件总大小
            long totalBytes = rep.ContentLength;
            //已经下载的大小
            long downloaded = 0;

            //缓存
            byte[] buffer = new byte[1024];
            //当前时间计算反馈周期用
            DateTime startTime = DateTime.Now;
            DateTime endTime;
            //下载量数组,用于计算速度
            Queue <double> insSpeeds = new Queue <double>(20);

            for (int i = 0; i < 20; i++)
            {
                insSpeeds.Enqueue(0.0);
            }
            //下载速度
            int speed = 0;


            //获取文件名
            string fileName = rep.ResponseUri.Segments.Last();
            //获取文件地址
            string modPath = Path.Combine(DirectoryPath, "mods", fileName);
            //临时下载文件地址(下载完成重命名,防止下载中断导致文件损坏)
            string tmpPath = modPath + ".cfdownload";

            //保存参数
            status.TotalBytes      = totalBytes;
            status.FileName        = fileName;
            status.Speed           = 0;
            status.DownloadedBytes = 0;


            //下载开始反馈
            status.IsBegin = true;
            DownBegin?.Invoke(this, status);


            if (File.Exists(modPath))
            {
                rep.Close();
                status.DownloadedBytes = status.TotalBytes;
                DownComplete?.Invoke(this, status);
                return;
            }

            #region  载具体实现
            //创建文件夹
            Directory.CreateDirectory(Path.Combine(DirectoryPath, "mods"));

            //保存流
            using (FileStream fsSave = new FileStream(tmpPath,
                                                      FileMode.Create, FileAccess.ReadWrite, FileShare.None))
            {
                //下载流
                using (Stream rsDown = rep.GetResponseStream())
                {
                    //单位时间内下载量
                    int periodBytes = 0;

                    int r = 1;
                    //循环读流
                    while (r > 0)
                    {
                        //计算速度
                        endTime = DateTime.Now;
                        TimeSpan span = endTime - startTime;

                        //速度计算周期50ms
                        if (span > TimeSpan.FromMilliseconds(50))
                        {
                            //瞬时速度
                            double insSpeed = periodBytes / span.TotalSeconds / 1024;

                            //重置计算
                            periodBytes = 0;
                            startTime   = DateTime.Now;

                            //计算平均速度
                            insSpeeds.Dequeue();
                            insSpeeds.Enqueue(insSpeed);
                            speed = (int)insSpeeds.Average();
                        }


                        //反馈进度
                        status.DownloadedBytes = downloaded;
                        status.Speed           = speed;

                        try
                        {
                            r = rsDown.Read(buffer, 0, 1024); //读流
                            fsSave.Write(buffer, 0, r);       //存流
                        }
                        catch (IOException)
                        {
                            fsSave.Close();
                            rsDown.Close();
                            DownloadModPrivate(status, tryTime + 1);
                            return;
                        }

                        //保存进度
                        downloaded  += r;
                        periodBytes += r;
                    }
                }
            }
            //下载完成,重命名文件(防止下载中断错误)
            if (File.Exists(modPath))
            {
                File.Delete(modPath);
            }
            File.Move(tmpPath, modPath);

            //下载完成反馈
            Thread.Sleep(100);
            DownComplete?.Invoke(this, status);
            #endregion
        }
 public void Begin(DownloadStatus status)
 {
     txtName.Text = status.FileName;
 }