/// <summary> /// Deletes any target files that are not listed in the source array. /// </summary> private void DeleteSourceFilesFromTarget(IEnumerable <string> sourceFiles, DirectoryInfo targetDirInfo) { // Get names only as lowercase for comparison string[] sourceFileNames = sourceFiles.Select(f => Path.GetFileName(f).ToLower()).ToArray(); // Get full paths to target (maintain case, UNIX names can be case sensitive.) string[] targetFiles = Directory.EnumerateFiles(targetDirInfo.FullName, "*.*", SearchOption.TopDirectoryOnly).ToArray(); // Need to check for files that exist in target but not in source foreach (string file in targetFiles) { // Compare names as lowercase string nameOnly = Path.GetFileName(file).ToLower(); // Only name will match, full paths are from different locations bool remove = !sourceFileNames.Contains(nameOnly); // Remove if ext is now excluded remove |= BackupSettings.IsFileTypeExcluded(file); // Remove if hidden options changed remove |= BackupSettings.IgnoreHiddenFiles && (File.GetAttributes(file) & FileAttributes.Hidden) > 0; if (remove) { // Delete using full path DeleteFile(file); } } }
/// <summary> /// Copies directory from source to target. /// </summary> /// <param name="sourceDirInfo">Source directory to copy</param> /// <param name="targetDirInfo">Target directory where backup is to take place</param> /// <returns>Number of files backed up</returns> protected int CopyFiles(DirectoryInfo sourceDirInfo, DirectoryInfo targetDirInfo) { int backupCount = 0; // Check source exists and whether hidden should be backup up. // (Files within a hidden directory are also considered hidden.) if (!BackupSettings.IgnoreHiddenFiles || (sourceDirInfo.Attributes & FileAttributes.Hidden) == 0) { // Remove common root path string sourceSubDir = GetSourceSubDir(sourceDirInfo.FullName, targetDirInfo.FullName); // Get target path string targetDir = Path.Combine(targetDirInfo.FullName, sourceSubDir); // Get qualifying files only var files = Directory.EnumerateFiles(sourceDirInfo.FullName, "*.*", SearchOption.TopDirectoryOnly).Where(f => !BackupSettings.IsFileTypeExcluded(f)); // Copy files in current directory backupCount = CopyFiles(files, targetDir); // Recursive call for sub directories foreach (DirectoryInfo subDirInfo in sourceDirInfo.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Where(d => !BackupSettings.IsDirectoryExcluded(d.Name))) { backupCount += CopyFiles(subDirInfo, targetDirInfo); } } return(backupCount); }
/// <summary> /// Remove directories/files from target that are not in source, /// then copies in new/updated files. /// </summary> private int SyncDirectories(string sourceDir, string targetDir) { DirectoryInfo sourceDirInfo = new(sourceDir); DirectoryInfo targetDirInfo = new(targetDir); // Get qualifying files only var sourceFiles = Directory.EnumerateFiles(sourceDirInfo.FullName, "*.*", SearchOption.TopDirectoryOnly).Where(f => !BackupSettings.IsFileTypeExcluded(f)); // Check if previous backup taken place if (targetDirInfo.Exists) { ////////////////////////////////////////////////////// // Remove directories from target not in source // (Remove before copying new files to free up space) ////////////////////////////////////////////////////// DeleteSourceDirectoriesFromTarget(sourceDirInfo, targetDirInfo); ////////////////////////////////////////////////////// // Remove files from target not in source // (Remove before copying new files to free up space) ////////////////////////////////////////////////////// DeleteSourceFilesFromTarget(sourceFiles, targetDirInfo); } int backupCount = 0; // Check whether backing up hidden directories if (!BackupSettings.IgnoreHiddenFiles || (sourceDirInfo.Attributes & FileAttributes.Hidden) == 0) { ////////////////////////////////////////////////////// // Copy files from source not in target // (Or replace old files) ////////////////////////////////////////////////////// backupCount = CopyFiles(sourceFiles, targetDir); ///////////////////////////////////////////// // Sync sub directories ///////////////////////////////////////////// foreach (DirectoryInfo subDirInfo in sourceDirInfo.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Where(d => !BackupSettings.IsDirectoryExcluded(d.Name))) { // Get sub-directories string subSourceDir = Path.Combine(sourceDir, subDirInfo.Name); string subTargetDir = Path.Combine(targetDir, subDirInfo.Name); // Recursive call backupCount += SyncDirectories(subSourceDir, subTargetDir); } } return(backupCount); }