当前位置: 首页 > news >正文

C# 备份文件夹

C# 备份目标文件夹

方法1:通过 递归 或者 迭代 结合 C# 方法

参数说明:

  • sourceFolder:源文件夹路径
  • destinationFolder:目标路径
  • excludeNames:源文件夹中不需备份的文件或文件夹路径哈希表
  • errorLog:输出错误log

递归实现

		private bool CopyAllFolder(string sourceFolder, string destinationFolder, HashSet<string> excludeNames, out string errorLog){errorLog = string.Empty;try{if (!Directory.Exists(destinationFolder)){Directory.CreateDirectory(destinationFolder);}string[] directories = Directory.GetDirectories(sourceFolder);string[] files = Directory.GetFiles(sourceFolder);foreach (string file in files){if (excludeNames.Count != 0 && excludeNames.Contains(file)){continue;}try{if (!BRTools.IsFileReady(file) || !BRTools.IsNotFileInUse(file, out errorLog)) // 检测文件是否被占用{return false;}string destinationFile = Path.Combine(destinationFolder, Path.GetFileName(file));File.Copy(file, destinationFile, true);}catch (Exception ex){errorLog += $"Error copying file '{file}': {ex.Message}\n";return false;}}foreach (string directory in directories){if (excludeNames.Count != 0 && excludeNames.Contains(directory)){continue;}string destinationSubFolder = Path.Combine(destinationFolder, Path.GetFileName(directory));if (!CopyAllFolder(directory, destinationSubFolder, excludeNames, out string subfolderErrorLog)){errorLog += subfolderErrorLog;return false;}}return true;}catch (Exception ex){errorLog = $"Error during folder copy: Message = '{ex.Message}', StackTrace = '{ex.StackTrace}'\n";return false;}}

迭代实现:

        private bool CopyAllFolder(string sourceFolder, string destinationFolder, HashSet<string> excludeNames, out string errorLog){errorLog = string.Empty;try{if (!Directory.Exists(destinationFolder)){Directory.CreateDirectory(destinationFolder);}Stack<string> directoryStack = new Stack<string>();directoryStack.Push(sourceFolder);while (directoryStack.Count > 0){string currentDirectory = directoryStack.Pop();string[] directories = Directory.GetDirectories(currentDirectory);string[] files = Directory.GetFiles(currentDirectory);foreach (string file in files){if (excludeNames.Count != 0 && excludeNames.Contains(file)){continue;}try{if (!BRTools.IsFileReady(file) || !BRTools.IsNotFileInUse(file, out errorLog)){return false;}string destinationFile = Path.Combine(destinationFolder, Path.GetFileName(file));File.Copy(file, destinationFile, true);}catch (Exception ex){errorLog += $"Error copying file '{file}': {ex.Message}\n";return false;}}foreach (string directory in directories){if (excludeNames.Count != 0 && excludeNames.Contains(directory)){continue;}string destinationSubFolder = Path.Combine(destinationFolder, Path.GetFileName(directory));if (!CopyAllFolder(directory, destinationSubFolder, excludeNames, out string subfolderErrorLog)){errorLog += subfolderErrorLog;return false;}directoryStack.Push(directory);}}return true;}catch (Exception ex){errorLog = $"Error during folder copy: Message = '{ex.Message}', StackTrace = '{ex.StackTrace}'\n";return false;}}

方法2:利用 Windows API

		[DllImport("shell32.dll", CharSet = CharSet.Auto)]public static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]public struct SHFILEOPSTRUCT{public IntPtr hwnd;public int wFunc;public string pFrom;public string pTo;public short fFlags;public bool fAnyOperationsAborted;public IntPtr hNameMappings;}const int FO_COPY = 0x0002;const int FOF_NOCONFIRMATION = 0x0010;const int FOF_SILENT = 0x0004;const int FOF_NO_UI = FOF_NOCONFIRMATION | FOF_SILENT;private bool CopyDirectory(string sourceDir, string destDir, out string errorLog){errorLog = string.Empty;try{SHFILEOPSTRUCT fileOp = new SHFILEOPSTRUCT();fileOp.wFunc = FO_COPY;fileOp.pFrom = sourceDir + '\0' + '\0';  // Must end with double null characterfileOp.pTo = destDir + '\0' + '\0';     // Must end with double null character//fileOp.fFlags = FOF_NO_UI;fileOp.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION;  // 忽略UI和确认对话框int result = SHFileOperation(ref fileOp);// 检查返回值if (result != 0){errorLog = $"SHFileOperation failed with error code: {result}";return false;}return true;}catch (Exception ex){errorLog = $"Failed to copy the entire folder '{sourceDir}': Message = '{ex.Message}', StackTrace = '{ex.StackTrace}'\n";return false;}}private bool CopyFolder(string sourceFolder, string destinationFolder, HashSet<string> excludeNames, out string errorLog){errorLog = string.Empty;try{if (!CopyDirectory(sourceFolder, destinationFolder, out errorLog)){this.logger.Warning($"errorLog: {errorLog}");return false;}if (excludeNames.Count != 0){foreach (var item in excludeNames){var targetPath = Path.Combine(destinationFolder, GetSonFolderPath(sourceFolder, item)); // 获取已备份路径下需排除的文件夹或文件路径if (Directory.Exists(item)){                                DeleteDir(targetPath);}if(File.Exists(item)){DeleteDir(targetPath);}}}return true;}catch(Exception ex){errorLog = $"Error during folder copy, and exception is: Message = '{ex.Message}', StackTrace = '{ex.StackTrace}'\n";return false;}}private string GetSonFolderPath(string folderPath, string targetPath){string result = string.Empty;try{folderPath = folderPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;if (!isFilePath(targetPath)){targetPath = targetPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;}else{targetPath = Path.GetDirectoryName(targetPath).TrimEnd(Path.DirectorySeparatorChar);}if (targetPath.StartsWith(folderPath, StringComparison.OrdinalIgnoreCase)){result = targetPath.Substring(folderPath.Length);}}catch (Exception){result = string.Empty;}return result;}private bool isFilePath(string targetPath){if (Path.HasExtension(targetPath) && File.Exists(targetPath))return true;return false;}private void DeleteFile(string file){if (File.Exists(file)){FileInfo fi = new FileInfo(file);if (fi.IsReadOnly){fi.IsReadOnly = false;}File.Delete(file);}}private void DeleteDir(string dir){if (Directory.Exists(dir)){foreach (string childName in Directory.GetFileSystemEntries(dir)){if (File.Exists(childName)){FileInfo fi = new FileInfo(childName);if (fi.IsReadOnly){fi.IsReadOnly = false;}File.Delete(childName);}elseDeleteDir(childName);}Directory.Delete(dir, true);}}

注意:方法2有一个漏洞,该方法无法成功捕捉到源文件夹下被占用的文件信息!

相关文章:

C# 备份文件夹

C# 备份目标文件夹 方法1&#xff1a;通过 递归 或者 迭代 结合 C# 方法 参数说明&#xff1a; sourceFolder&#xff1a;源文件夹路径destinationFolder&#xff1a;目标路径excludeNames&#xff1a;源文件夹中不需备份的文件或文件夹路径哈希表errorLog&#xff1a;输出错…...

互联网信息泄露与安全扫描工具汇总

文章目录 1. 代码托管平台渠道泄露2. 网盘渠道泄露3. 文章渠道泄露4. 文档渠道泄露5. 暗网渠道泄露6. 互联网IP信誉度排查7. 网站挂马暗链扫描8. 互联网IP端口扫描9. 互联网资产漏洞扫描 1. 代码托管平台渠道泄露 https://github.com/ https://gitee.com/ https://gitcode.co…...

主导极点,传递函数零极点与时域模态

运动模态 控制系统的数学建模&#xff0c;可以采用微分方程或传递函数&#xff0c;两者具有相同的特征方程。在数学上&#xff0c;微分方程的解由特解和通解组成&#xff0c;具体求解过程可以参考&#xff1a;微分方程求解的三种解析方法。 如果 n n n阶微分方程&#xff0c;具…...

永恒之蓝漏洞利用什么端口

永恒之蓝&#xff08;EternalBlue&#xff09;是一个著名的漏洞&#xff0c;影响了 Windows 操作系统的 SMBv1 服务。它的漏洞编号是 CVE-2017-0144&#xff0c;该漏洞被用于 WannaCry 等勒索病毒的传播。 永恒之蓝漏洞利用的端口 永恒之蓝漏洞利用的是 SMB&#xff08;Server…...

网络安全与防范

1.重要性 随着互联网的发达&#xff0c;各种WEB应用也变得越来越复杂&#xff0c;满足了用户的各种需求&#xff0c;但是随之而来的就是各种网络安全的问题。了解常见的前端攻击形式和保护我们的网站不受攻击是我们每个优秀fronter必备的技能。 2.分类 XSS攻击CSRF攻击网络劫…...

Navicat 17 功能简介 | SQL 开发

Navicat 17 功能简介 | SQL 开发 随着 17 版本的发布&#xff0c;Navicat 也带来了众多的新特性&#xff0c;包括兼容更多数据库、全新的模型设计、可视化智能 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展 MongoDB 功能、轻松固定查询结果、便捷URI…...

嵌入式系统中的并行编程模型:汇总解析与应用

概述&#xff1a;随着嵌入式系统处理能力的不断提升&#xff0c;并行编程在其中的应用愈发广泛。本文深入探讨了多种专门为嵌入式设计的并行编程模型&#xff0c;包括任务队列模型、消息传递模型、数据并行模型、异构多核并行模型、实时任务调度模型以及函数式并行模型。详细阐…...

VulkanSamples编译记录

按照BUILD.md说明&#xff0c;先安装依赖项 sudo apt-get install git build-essential libx11-xcb-dev \libxkbcommon-dev libwayland-dev libxrandr-dev 然后创建一个新文件夹build&#xff0c;在该目录下更新依赖项 cd VulkanSamples mkdir build cd build python ../scr…...

使用FabricJS对大图像应用滤镜(巨坑)

背景:我司在canvas的渲染模板的宽高都大于2048px 都几乎接近4000px&#xff0c;就导致使用FabricJS的滤镜功能图片显示异常 新知识:滤镜是对图片纹理的处理 FabricJS所能支持的最大图片纹理是2048的 一但图片超出2048的纹理尺寸 当应用滤镜时&#xff0c;图像会被剪切或者是缩…...

网页502 Bad Gateway nginx1.20.1报错与解决方法

目录 网页报错的原理 查到的502 Bad Gateway报错的原因 出现的问题和尝试解决 问题 解决 网页报错的原理 网页显示502 Bad Gateway 报错原理是用户访问服务器时&#xff0c;nginx代理服务器接收用户信息&#xff0c;但无法反馈给服务器&#xff0c;而出现的报错。 查到…...

Spring基础分析02-BeanFactory与ApplicationContext

大家好&#xff0c;今天和大家一起学习整理一下Spring 的BeanFactory和ApplicationContext内容和区别~ BeanFactory和ApplicationContext是Spring IoC容器的核心组件&#xff0c;负责管理应用程序中的Bean生命周期和配置。我们深入分析一下这两个接口的区别、使用场景及其提供…...

Rerender A Video 技术浅析(五):对象移除与自动配色

Rerender A Video 是一种基于深度学习和计算机视觉技术的视频处理工具&#xff0c;旨在通过智能算法对视频进行重新渲染和优化。 一、对象移除模块 1. 目标检测 1.1 概述 目标检测是对象移除的第一步&#xff0c;旨在识别视频中需要移除的对象并生成相应的掩码&#xff08;m…...

Java项目实战II基于微信小程序的小区租拼车管理信息系统 (开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着城市化进程的加速&#xff0c;小区居民对于出行方…...

【数字花园】数字花园(个人网站、博客)搭建经历汇总教程

目录 写在最最前面第一章&#xff1a;netlify免费搭建数字花园相关教程使用的平台步骤信息管理 第二章&#xff1a;本地部署数字花园数字花园网站本地手动部署方案1. 获取网站源码2.2 安装 Node.js 3. 项目部署3.1 安装项目依赖3.2 构建项目3.3 启动http服务器 4. 本地预览5. 在…...

WebRTC服务质量(03)- RTCP协议

一、前言&#xff1a; RTCP&#xff08;RTP Control Protocol&#xff09;是一种控制协议&#xff0c;与RTP&#xff08;Real-time Transport Protocol&#xff09;一起用于实时通信中的控制和反馈。RTCP负责监控和调节实时媒体流。通过不断交换RTCP信息&#xff0c;WebRTC应用…...

STM32F103单片机HAL库串口通信卡死问题解决方法

在上篇文章 STM32F103单片机使用STM32CubeMX创建IAR串口工程 中分享了使用cubeMX直接生成串口代码的方法&#xff0c;在测试的过程中无意间发现&#xff0c;串口会出现卡死的问题。 当串口一次性发送十几个数据的时候&#xff0c;串口感觉像卡死了一样&#xff0c;不再接收数据…...

Scala正则表达式

一、定义&#xff1a;正则表达式是一种用于匹配、查找和替换文本中特定模式的字符串。 使用方式&#xff1a;①定义一个正则 正则表达式应用场景&#xff1a;查找、验证、替换。 Ⅰ、查找 在目标字符串中&#xff0c;找到符合正则表达式规则要求的 子串。 方括号&#xff…...

每日一刷——二叉树的构建——12.12

第一题&#xff1a;最大二叉树 题目描述&#xff1a;654. 最大二叉树 - 力扣&#xff08;LeetCode&#xff09; 我的想法&#xff1a; 我感觉这个题目最开始大家都能想到的暴力做法就是遍历找到数组中的最大值&#xff0c;然后再遍历一遍&#xff0c;把在它左边的依次找到最大…...

Redis配置文件中 supervised指令

什么是Supervised&#xff1f; supervised模式允许Redis被外部进程管理器监控。通过这个选项&#xff0c;Redis能够在崩溃后自动重启&#xff0c;确保服务的高可用性。常见的进程管理器包括systemd和upstart。 开启方法 vim修改&#xff1a; sudo vi /etc/redis/redis.conf…...

OpenCV相机标定与3D重建(18)根据基础矩阵(Fundamental Matrix)校正两组匹配点函数correctMatches()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 优化对应点的坐标。 cv::correctMatches 是 OpenCV 库中的一个函数&#xff0c;用于根据基础矩阵&#xff08;Fundamental Matrix&#xff09;校…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟

众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了&#xff0c;延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp &#xff0c;边缘服务器拉流推送到云服务器 …...