Beispiel #1
0
        /// <summary>
        /// 同步文件夹,使两文件夹的数据保持一致(支持直接调用)
        /// </summary>
        /// <param name="origin">源文件夹的绝对路径</param>
        /// <param name="destination">目标文件夹的绝对路径</param>
        /// <param name="STACHK_flag">文件一致性检验标识(见"FLAG_STACHK_xxx"),如有多个标识,请使用或运算("|")</param>
        public void Direct_Sync_File(string origin, string destination, int STACHK_flag = FLAG_STACHK_DIRECT_SYNC_DEFAULT, bool include_hidden_dir_and_file = false, List<string> include_ext = null, List<string> escape_ext = null)
        {
            //todo: 加上文件拓展名检验排除

            //验证文件夹合理与否 & 创建目标文件夹
            DirectoryInfo odi, ddi;
            odi = new DirectoryInfo(origin);
            if (odi.Exists == false)
            {
                //源文件夹不存在,抛出异常,退出函数
                throw new DirectoryNotFoundException("同步源文件夹 " + origin + " 不存在");
            }
            ddi = new DirectoryInfo(destination);
            if (ddi.Exists == false)
            {
                //目标文件夹不存在,创建
                ddi.Create();
            }

            //二期新增代码 - 初始化拓展名表
            if (include_ext == null) include_ext = new List<string>();
            if (escape_ext == null) escape_ext = new List<string>();
            bool has_include_ext = include_ext.Count > 0 ? true : false;
            bool has_escape_ext = escape_ext.Count > 0 ? true : false;
            //拓展名重复检测
            if(has_include_ext && has_escape_ext)
            {
                IEnumerable<string> repeat_ext = include_ext.Intersect(escape_ext);
                foreach (string item in repeat_ext)
                    throw new InvalidDataException("在包括和排除的拓展名中重复出现:" + item);
            }

            //获取文件目录
            odi = new DirectoryInfo(origin);
            ddi = new DirectoryInfo(destination);

            //源文件夹和目标文件夹里的文件分为3中状态
            //1 源文件夹有,目标文件夹没有,则可以无视文件检验过程(直接复制到新的文件夹中)
            //2 目标文件夹有,源文件夹没有,也可以无视文件检验过程(直接从目标文件夹里删除)
            //3 两个都有,则要进行文件验证
            List<string> ls_str_ofi = new List<string>(), ls_str_dfi = new List<string>();
            foreach (FileInfo item in odi.GetFiles())
            {
                //按后缀名分类
                if (has_include_ext)
                    if (!include_ext.Contains(item.Extension)) continue;
                if (has_escape_ext)
                    if (escape_ext.Contains(item.Extension)) continue;
                //二期代码 - 隐藏文件会因没有开启hidden而跳过
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0) continue;

                ls_str_ofi.Add(item.Name);
            }

            foreach (FileInfo item in ddi.GetFiles())
                ls_str_dfi.Add(item.Name);

            //集合运算: 源文件名 - 目标文件名  -> 要复制的文件名
            IEnumerable<string> copy_file = ls_str_ofi.Except(ls_str_dfi);
            //集合运算: 目标文件名 - 源文件名 -> 要删除的文件名
            IEnumerable<string> delete_file = ls_str_dfi.Except(ls_str_ofi);
            //集合运算: 源文件名 ∩ 目标文件名 -> 要验证复制的文件名
            IEnumerable<string> copy_to_be_validated = ls_str_ofi.Intersect(ls_str_dfi);

            //todo: 引发一下文件IO异常,验证代码逻辑 → 这么作死谁拦你啊(╯‵□′)╯︵┻━┻
            #region File_Operation
            //复制文件开始
            foreach (string item in copy_file)
            {
                bool suc = false;
                do
                {
                    try
                    {
                        _Copy_File(odi.FullName + "/" + item, ddi.FullName + "/" + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因复制文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("复制 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                                throw;
                            if (e.retry == false && e.ignore == true)
                                suc = true;
                        }
                        else
                            throw;
                    }
                } while(!suc);
            }

            //删除文件开始
            foreach (string item in delete_file)
            {
                bool suc = false;
                do
                {
                    try
                    {
                        _Delete_File(ddi.FullName + '/' + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因删除文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("删除 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                                throw;
                            if (e.retry == false && e.ignore == true)
                                suc = true;
                        }
                        else
                            throw;
                    }
                } while(!suc);
            }

            //验证+复制文件开始
            foreach (string item in copy_to_be_validated)
            {
                //验证文件
                bool file_skip = false;
                bool suc = false;
                do
                {
                    try
                    {
                        file_skip = _File_Validating(odi.FullName + '/' + item, ddi.FullName + '/' + item, STACHK_flag);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因验证文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("验证 " + odi.FullName + '/' + item + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                                throw;
                            if (e.retry == false && e.ignore == true)
                                suc = true;
                        }
                        else
                            throw;
                    }
                } while(!suc);

                if (file_skip)
                    continue;
                //复制文件
                suc = false;
                do
                {
                    try
                    {
                        _Copy_File(odi.FullName + "/" + item, ddi.FullName + "/" + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因复制文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("复制 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                                throw;
                            if (e.retry == false && e.ignore == true)
                                suc = true;
                        }
                        else
                            throw;
                    }
                } while(!suc);
            }

            #endregion

            //函数递归调用同步子文件夹,原理同上,懒得开局部变量了,直接用了,原理跟上面一样,只不过是从文件换成文件夹了,所以就不注释了
            #region Directory_Operation
            //二期新增:文件夹是否隐藏判定
            ls_str_ofi.Clear();
            ls_str_dfi.Clear();
            foreach (DirectoryInfo item in odi.GetDirectories())
            {
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0) continue;
                ls_str_ofi.Add(item.Name);
            }
            foreach (DirectoryInfo item in ddi.GetDirectories())
            {
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0) continue;
                ls_str_dfi.Add(item.Name);
            }

            copy_file = ls_str_ofi.Except(ls_str_dfi);
            delete_file = ls_str_dfi.Except(ls_str_ofi);
            copy_to_be_validated = ls_str_ofi.Union(ls_str_dfi);

            foreach (string item in copy_file)
                Direct_Sync_File(origin + '/' + item, destination + '/' + item, STACHK_flag, include_hidden_dir_and_file, include_ext, escape_ext);
            foreach (string item in delete_file)
                Directory.Delete(destination + '/' + item, true);
            foreach (string item in copy_to_be_validated)
                Direct_Sync_File(origin + '/' + item, destination + '/' + item, STACHK_flag, include_hidden_dir_and_file, include_ext, escape_ext);
            #endregion
        }
Beispiel #2
0
        /// <summary>
        /// 同步文件夹,使两文件夹的数据保持一致(支持直接调用)
        /// </summary>
        /// <param name="origin">源文件夹的绝对路径</param>
        /// <param name="destination">目标文件夹的绝对路径</param>
        /// <param name="STACHK_flag">文件一致性检验标识(见"FLAG_STACHK_xxx"),如有多个标识,请使用或运算("|")</param>
        public void Direct_Sync_File(string origin, string destination, int STACHK_flag = FLAG_STACHK_DIRECT_SYNC_DEFAULT, bool include_hidden_dir_and_file = false, List <string> include_ext = null, List <string> escape_ext = null)
        {
            //todo: 加上文件拓展名检验排除

            //验证文件夹合理与否 & 创建目标文件夹
            DirectoryInfo odi, ddi;

            odi = new DirectoryInfo(origin);
            if (odi.Exists == false)
            {
                //源文件夹不存在,抛出异常,退出函数
                throw new DirectoryNotFoundException("同步源文件夹 " + origin + " 不存在");
            }
            ddi = new DirectoryInfo(destination);
            if (ddi.Exists == false)
            {
                //目标文件夹不存在,创建
                ddi.Create();
            }

            //二期新增代码 - 初始化拓展名表
            if (include_ext == null)
            {
                include_ext = new List <string>();
            }
            if (escape_ext == null)
            {
                escape_ext = new List <string>();
            }
            bool has_include_ext = include_ext.Count > 0 ? true : false;
            bool has_escape_ext  = escape_ext.Count > 0 ? true : false;

            //拓展名重复检测
            if (has_include_ext && has_escape_ext)
            {
                IEnumerable <string> repeat_ext = include_ext.Intersect(escape_ext);
                foreach (string item in repeat_ext)
                {
                    throw new InvalidDataException("在包括和排除的拓展名中重复出现:" + item);
                }
            }

            //获取文件目录
            odi = new DirectoryInfo(origin);
            ddi = new DirectoryInfo(destination);

            //源文件夹和目标文件夹里的文件分为3中状态
            //1 源文件夹有,目标文件夹没有,则可以无视文件检验过程(直接复制到新的文件夹中)
            //2 目标文件夹有,源文件夹没有,也可以无视文件检验过程(直接从目标文件夹里删除)
            //3 两个都有,则要进行文件验证
            List <string> ls_str_ofi = new List <string>(), ls_str_dfi = new List <string>();

            foreach (FileInfo item in odi.GetFiles())
            {
                //按后缀名分类
                if (has_include_ext)
                {
                    if (!include_ext.Contains(item.Extension))
                    {
                        continue;
                    }
                }
                if (has_escape_ext)
                {
                    if (escape_ext.Contains(item.Extension))
                    {
                        continue;
                    }
                }
                //二期代码 - 隐藏文件会因没有开启hidden而跳过
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0)
                {
                    continue;
                }

                ls_str_ofi.Add(item.Name);
            }

            foreach (FileInfo item in ddi.GetFiles())
            {
                ls_str_dfi.Add(item.Name);
            }

            //集合运算: 源文件名 - 目标文件名  -> 要复制的文件名
            IEnumerable <string> copy_file = ls_str_ofi.Except(ls_str_dfi);
            //集合运算: 目标文件名 - 源文件名 -> 要删除的文件名
            IEnumerable <string> delete_file = ls_str_dfi.Except(ls_str_ofi);
            //集合运算: 源文件名 ∩ 目标文件名 -> 要验证复制的文件名
            IEnumerable <string> copy_to_be_validated = ls_str_ofi.Intersect(ls_str_dfi);

            //todo: 引发一下文件IO异常,验证代码逻辑 → 这么作死谁拦你啊(╯‵□′)╯︵┻━┻
            #region File_Operation
            //复制文件开始
            foreach (string item in copy_file)
            {
                bool suc = false;
                do
                {
                    try
                    {
                        _Copy_File(odi.FullName + "/" + item, ddi.FullName + "/" + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因复制文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("复制 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                            {
                                throw;
                            }
                            if (e.retry == false && e.ignore == true)
                            {
                                suc = true;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while(!suc);
            }

            //删除文件开始
            foreach (string item in delete_file)
            {
                bool suc = false;
                do
                {
                    try
                    {
                        _Delete_File(ddi.FullName + '/' + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因删除文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("删除 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                            {
                                throw;
                            }
                            if (e.retry == false && e.ignore == true)
                            {
                                suc = true;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while(!suc);
            }

            //验证+复制文件开始
            foreach (string item in copy_to_be_validated)
            {
                //验证文件
                bool file_skip = false;
                bool suc       = false;
                do
                {
                    try
                    {
                        file_skip = _File_Validating(odi.FullName + '/' + item, ddi.FullName + '/' + item, STACHK_flag);
                        suc       = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因验证文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("验证 " + odi.FullName + '/' + item + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                            {
                                throw;
                            }
                            if (e.retry == false && e.ignore == true)
                            {
                                suc = true;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while(!suc);

                if (file_skip)
                {
                    continue;
                }
                //复制文件
                suc = false;
                do
                {
                    try
                    {
                        _Copy_File(odi.FullName + "/" + item, ddi.FullName + "/" + item);
                        suc = true;
                    }
                    catch (Exception ex)
                    {
                        //处理因复制文件引发的异常
                        if (File_Operation_Error != null)
                        {
                            File_Operation_Error_Event_Arg e = new File_Operation_Error_Event_Arg();
                            e.ex = new InvalidOperationException("复制 " + odi.FullName + " 时发生错误", ex);
                            File_Operation_Error(ref e);
                            //不重试/取消,则抛出异常,交由上一调用堆栈处理
                            if (e.cancel)
                            {
                                throw;
                            }
                            if (e.retry == false && e.ignore == true)
                            {
                                suc = true;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while(!suc);
            }

            #endregion

            //函数递归调用同步子文件夹,原理同上,懒得开局部变量了,直接用了,原理跟上面一样,只不过是从文件换成文件夹了,所以就不注释了
            #region Directory_Operation
            //二期新增:文件夹是否隐藏判定
            ls_str_ofi.Clear();
            ls_str_dfi.Clear();
            foreach (DirectoryInfo item in odi.GetDirectories())
            {
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0)
                {
                    continue;
                }
                ls_str_ofi.Add(item.Name);
            }
            foreach (DirectoryInfo item in ddi.GetDirectories())
            {
                if (!include_hidden_dir_and_file && (item.Attributes & FileAttributes.Hidden) != 0)
                {
                    continue;
                }
                ls_str_dfi.Add(item.Name);
            }

            copy_file            = ls_str_ofi.Except(ls_str_dfi);
            delete_file          = ls_str_dfi.Except(ls_str_ofi);
            copy_to_be_validated = ls_str_ofi.Union(ls_str_dfi);

            foreach (string item in copy_file)
            {
                Direct_Sync_File(origin + '/' + item, destination + '/' + item, STACHK_flag, include_hidden_dir_and_file, include_ext, escape_ext);
            }
            foreach (string item in delete_file)
            {
                Directory.Delete(destination + '/' + item, true);
            }
            foreach (string item in copy_to_be_validated)
            {
                Direct_Sync_File(origin + '/' + item, destination + '/' + item, STACHK_flag, include_hidden_dir_and_file, include_ext, escape_ext);
            }
            #endregion
        }