示例#1
0
        /// <summary>
        /// 尝试把目标文件剪切到备份文件夹下,如果目标文件存在才会移动备份
        /// </summary>
        /// <param name="localFileItem"></param>
        private void TryBackupOneFile(LocalFileItem localFileItem)
        {
            try
            {
                //检查创建备份文件的所在目录
                FileHelper.CheckCreateParentDir(localFileItem.backupFilePath);

                if (File.Exists(localFileItem.targetFilePath))
                {
                    //尝试先删除备份文件
                    if (File.Exists(localFileItem.backupFilePath))
                    {
                        File.Delete(localFileItem.backupFilePath);
                    }

                    //把需要备份的文件移动到备份文件夹。
                    File.Move(localFileItem.targetFilePath, localFileItem.backupFilePath);
                    Log.Info($"UpdateTask.TryBackupOneFile(): 移动目标文件到备份文件夹 {localFileItem.fileItem.relativePath}");

                    //记录备份文件
                    backupFileList.Add(localFileItem);
                }
            }
            catch (Exception e)
            {
                Log.Error($"UpdateTask.TryBackupOneFile(): 移动目标文件{localFileItem.fileItem.relativePath}到备份文件夹时异常:" + e.Message);
            }
        }
示例#2
0
        /// <summary>
        /// 使用一个服务器上下下来的FolderConfig,加上本地配置LocalSetting。
        /// 初始化自己的整个内容
        /// </summary>
        /// <param name="fileItemDict"></param>
        public void InitWithFolderConfig(ConcurrentDictionary <string, FileItem> fileItemDict)
        {
            //先clear
            fileItemClientDict.Clear();

            foreach (var fileItem in fileItemDict.Values)
            {
                LocalFileItem fic = new LocalFileItem();
                fic.fileItem       = fileItem;
                fic.tempFilePath   = Path.Combine(localSetting.tempFolderPath, fic.fileItem.relativePath);
                fic.targetFilePath = Path.Combine(localSetting.targetFolderPath, fic.fileItem.relativePath);
                fic.backupFilePath = Path.Combine(localSetting.backupFolderPath, fic.fileItem.relativePath);

                fileItemClientDict.Add(fic.fileItem.relativePath, fic);
            }
        }
示例#3
0
        /// <summary>
        /// 把备份文件恢复到目标文件。
        /// </summary>
        public void RecoverFile()
        {
            //先把改动过的文件移动回临时文件夹
            for (int i = 0; i < hasMoveFileList.Count; i++)
            {
                LocalFileItem localFileItem = hasMoveFileList[i];

                if (!File.Exists(localFileItem.targetFilePath))
                {
                    continue;
                }

                if (File.Exists(localFileItem.tempFilePath))
                {
                    File.Delete(localFileItem.tempFilePath);
                }

                //把目标文件移动到临时文件
                File.Move(localFileItem.targetFilePath, localFileItem.tempFilePath);
                Log.Info($"UpdateTask.RecoverFile(): 把目标文件移动到临时文件 {localFileItem.fileItem.relativePath}");
            }

            //遍历备份文件列表
            for (int i = 0; i < backupFileList.Count; i++)
            {
                LocalFileItem localFileItem = backupFileList[i];

                if (!File.Exists(localFileItem.backupFilePath))
                {
                    continue;
                }

                if (File.Exists(localFileItem.targetFilePath))
                {
                    File.Delete(localFileItem.targetFilePath);
                }

                //剪切备份文件到目标文件
                File.Move(localFileItem.backupFilePath, localFileItem.targetFilePath);
                Log.Info($"UpdateTask.RecoverFile(): 把备份文件恢复到目标文件 {localFileItem.fileItem.relativePath}");
            }

            Log.Info($"UpdateTask.RecoverFile(): 备份文件恢复到目标文件结束");
            hasMoveFileList.Clear();
            backupFileList.Clear();
        }
示例#4
0
        /// <summary>
        /// 从临时文件移动到目标文件,这是一个阻塞函数。如果在主线程中可能应该异步调用执行。但是这样最后会导致事件无法回到主线程。
        /// </summary>
        /// <returns></returns>
        public void MoveFile()
        {
            Log.Info($"UpdateTask.MoveFile(): 开始移动文件!!!");

            //清空备份列表的记录
            backupFileList.Clear();
            hasMoveFileList.Clear();

            try
            {
                foreach (var kv in localFolder.fileItemClientDict)
                {
                    LocalFileItem localFileItem = kv.Value;

                    //如果目标文件是否已经存在,目标文件和临时文件的md5是否一致。都不成立就备份目标文件到备份文件夹下。
                    if (File.Exists(localFileItem.targetFilePath) &&
                        //localFileItem.fileItem.MD5 ==  MD5Helper.FileMD5(localFileItem.targetFilePath))//<-----这里重新计算了一次MD5
                        localFileItem.fileItem.MD5 == localFileItem.lastTargetMD5)  //暂时不再重新计算一次了
                    {
                        Log.Info($"UpdateTask.MoveFile(): 不需要移动文件 {localFileItem.targetFilePath}");
                        continue;
                    }
                    else
                    {
                        //尝试把目标文件剪切到备份文件夹下,如果目标文件存在才会移动备份
                        if (File.Exists(localFileItem.targetFilePath))
                        {
                            TryBackupOneFile(localFileItem);
                        }
                    }

                    //检查创建目标文件的所在目录。
                    FileHelper.CheckCreateParentDir(localFileItem.targetFilePath);

                    //从临时文件移动到目标文件
                    if (File.Exists(localFileItem.tempFilePath))
                    {
                        Log.Info($"UpdateTask.MoveFile(): 移动临时文件到目标文件夹下-> {localFileItem.fileItem.relativePath}");
                        File.Move(localFileItem.tempFilePath, localFileItem.targetFilePath);
                        hasMoveFileList.Add(localFileItem);
                    }
                    else
                    {
                        Log.Error($"UpdateTask.MoveFile(): 源路径不存在 : {localFileItem.tempFilePath}, 无法剪切。");
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warning($"UpdateTask.MoveFile(): 移动文件异常 {e}");
                OnException();
            }

            //移动结束后,比对目标文件和xml的md5是否一致
            if (CheckTargetFileMD5WithXML())
            {
                Log.Info("UpdataTask.MoveFile(): 移动文件成功");

                if (null != EventMoveDone)
                {
                    EventMoveDone(this, true);
                }
            }
            else
            {
                if (null != EventError)
                {
                    EventError(new Exception());
                }
                Log.Info("UpdataTask.MoveFile(): 移动文件出错,移动后文件和服务器的不一致");
            }
        }
示例#5
0
        /// <summary>
        /// 由一个FileItemTask下载一项文件的方法
        /// </summary>
        /// <param name="localFileItem"></param>
        /// <returns></returns>
        private async Task DownLoadOneFile(LocalFileItem localFileItem)
        {
            if (!localFileItem.IsNeedDownload)//之前的MD5比对不需要下载就不下了
            {
                return;
            }
            Log.Info("UpdateTask.DownLoadOneFile():开始下载文件项: " + localFileItem.fileItem.url);
            FileItem fileItem = localFileItem.fileItem;

            if (File.Exists(localFileItem.tempFilePath))//如果已经下过一个了
            {
                if (MD5Helper.Compare(localFileItem.tempFilePath, localFileItem.fileItem.MD5, localFileItem.fileItem.size))
                {
                    //那么这个文件就不需要下载了
                    Log.Info("UpdateTask.DownLoadOneFile():存在一致的临时文件" + localFileItem.fileItem.relativePath);
                    localFileItem.IsNeedDownload = false;//标记它不用下载了
                    return;
                }
                else
                {
                    File.Delete(localFileItem.tempFilePath);//如果下好的临时文件MD5不一致,那么就删除这个以前的临时文件
                }
            }

            //如果这个临时文件所在的上级文件夹不存在那么就创建
            FileHelper.CheckCreateParentDir(localFileItem.tempFilePath);

            int isDone = 0;

            Interlocked.Exchange(ref isDone, 0);

            FileStream fs = null;

            //需要下载的文件是空文件,不用下载,本地直接创建一个空文件就行了。
            if (localFileItem.fileItem.size == 0)
            {
                fs = new FileStream(localFileItem.tempFilePath, FileMode.Create);
                fs.Close();
                return;
            }

            try
            {
                //下载文件的后缀加上.temp
                fs = new FileStream(localFileItem.tempFilePath + ".temp", FileMode.OpenOrCreate);

                Log.Info("UpdateTask.DownLoadOneFile():开始http连接...");
                Http.Get(fileItem.url)
                .OnMake((req) =>
                {
                    req.AddRange(fs.Length);//设置断点续传
                })
                .OnSuccess((WebHeaderCollection collection, Stream stream) =>
                {
                    try
                    {
                        fs.Seek(fs.Length, SeekOrigin.Begin);
                        CopyStream(stream, fs);//阻塞的下载?但是进入OnSuccess会是一个异步小线程
                        Log.Info("UpdateTask.DownLoadOneFile():下载成功!");
                    }
                    catch (Exception e)
                    {
                        Log.Error($"UpdateTask.DownLoadOneFile.CopyStream():{fileItem.url}下载异常:" + e.Message);
                        //EventError?.Invoke(e); //暂时不传出事件了
                    }
                    fs.Close();

                    Interlocked.Increment(ref isDone);//下载完成
                })
                .OnFail((e) =>
                {
                    if (fs != null)
                    {
                        fs.Close();
                    }

                    Log.Error($"UpdateTask.DownLoadOneFile.OnFail():{fileItem.url}下载异常:" + e.Message);
                    //EventError?.Invoke(e); //暂时不传出事件了

                    Interlocked.Increment(ref isDone);//下载完成
                }).Go();

                while (true)
                {
                    Log.Debug("UpdateTask.DownLoadOneFile():await Task.Delay(1)之前 当前执行线程id=" + Thread.CurrentThread.ManagedThreadId);
                    await Task.Delay(1);

                    Log.Debug("UpdateTask.DownLoadOneFile():await Task.Delay(1)之后 当前执行线程id=" + Thread.CurrentThread.ManagedThreadId);
                    //await WaitDelay();
                    if (isDone > 0)
                    {
                        break;
                    }
                }
                //下载成功后把文件名的.temp去掉
                File.Move(localFileItem.tempFilePath + ".temp", localFileItem.tempFilePath);
            }
            catch (Exception e)
            {
                Log.Error("UpdateTask.DownLoadOneFile():下载异常:" + e.Message);
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }