C#備份文件夾的兩種方法
方法1:通過 遞歸 或者 迭代 結(jié)合 C# 方法
參數(shù)說明:
- sourceFolder:源文件夾路徑
- destinationFolder:目標(biāo)路徑
- excludeNames:源文件夾中不需備份的文件或文件夾路徑哈希表
- errorLog:輸出錯(cuò)誤log
遞歸實(shí)現(xiàn):
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)) // 檢測(cè)文件是否被占用 { 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; } }
迭代實(shí)現(xiàn):
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 character fileOp.pTo = destDir + '\0' + '\0'; // Must end with double null character //fileOp.fFlags = FOF_NO_UI; fileOp.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION; // 忽略UI和確認(rèn)對(duì)話框 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); } else DeleteDir(childName); } Directory.Delete(dir, true); } }
注意:方法2有一個(gè)漏洞,該方法無法成功捕捉到源文件夾下被占用的文件信息!
到此這篇關(guān)于C#備份文件夾的兩種方法的文章就介紹到這了,更多相關(guān)C#備份文件夾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Quartz.Net任務(wù)和觸發(fā)器實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12Unity多語(yǔ)言轉(zhuǎn)換工具的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Unity多語(yǔ)言轉(zhuǎn)換工具的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06C#?Winform消息通知系統(tǒng)托盤氣泡提示框ToolTip控件
這篇文章主要為大家介紹了C#或Winform中的消息通知之系統(tǒng)托盤的氣泡提示框窗口(系統(tǒng)toast通知)、ToolTip控件和ToolTipText屬性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08C#啟動(dòng)windows服務(wù)方法的相關(guān)問題分析
C#啟動(dòng)windows服務(wù)的方法都是什么呢?C#啟動(dòng)服務(wù)類型為Disabled的windows服務(wù)會(huì)遇到什么樣的問題呢?那么本文就向你介紹C#啟動(dòng)windows服務(wù)的方法的相關(guān)內(nèi)容2012-12-12.NET 某云采購(gòu)平臺(tái)API 掛死問題解析
這篇文章主要介紹了.NET 某云采購(gòu)平臺(tái)API 掛死問題解析,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11