Ejemplo n.º 1
0
        public static int SyncXmlPairs(XmlConfig opts)
        {
            ProgressReporter.Logger = new Logger(opts.LogFilePath.Replace("\\", "/"), opts.FlushDelay);

            if (opts.ConfigFilePath == null || opts.ConfigFilePath.Count < 1)
            {
                return(1);
            }

            List <string> filepaths = opts.ConfigFilePath.ToList();
            PairConfig    pairConfig;

            for (int k = 0; k < filepaths.Count; k++)
            {
                string cleanedFilepath = filepaths[k].Replace("\\", "/");
                var    serializer      = new XmlSerializer(typeof(PairConfig));
                using (var xml = new FileStream(cleanedFilepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    pairConfig = (PairConfig)serializer.Deserialize(xml);
                }

                // Init pattern if it was missing in the xml config file
                for (int i = 0; i < pairConfig.PairArray.Length; i++)
                {
                    Pair p = pairConfig.PairArray[i];
                    if (p.FilterPattern == null || p.FilterPattern.Length == 0)
                    {
                        p.FilterPattern = "*";
                    }

                    if (p.IgnoreList == null)
                    {
                        p.IgnoreList = new string[0];
                    }
                    else
                    {
                        for (int j = 0; j < p.IgnoreList.Length; j++)
                        {
                            p.IgnoreList[j] = p.IgnoreList[j].Replace("\\", "/");
                        }
                    }
                }

                Options.ComparisonMode comparisonMode = pairConfig.ComparisonMode ?? Options.ComparisonMode.Date;

                // List all drives in the system
                Dictionary <string, char> DriveMapping         = new Dictionary <string, char>();
                Dictionary <char, string> OverrideDriveMapping = new Dictionary <char, string>();

                foreach (var item in System.IO.DriveInfo.GetDrives())
                {
                    // avoid crash when drives are disconnected
                    try
                    {
                        DriveMapping.Add(item.VolumeLabel, item.Name[0]);
                    }
                    catch (Exception) { }
                }

                if (pairConfig.DriveConfigArray != null)
                {
                    for (int i = 0; i < pairConfig.DriveConfigArray.Length; i++)
                    {
                        if (pairConfig.DriveConfigArray[i].Letter == null || pairConfig.DriveConfigArray[i].Letter.Length != 1)
                        {
                            throw new System.Exception("Invalid Drive Config letter");
                        }

                        OverrideDriveMapping.TryAdd(pairConfig.DriveConfigArray[i].Letter[0], pairConfig.DriveConfigArray[i].Label);
                    }
                }

                if (k > 0)
                {
                    ProgressReporter.Logger.WriteLine(" ");
                }
                ProgressReporter.Logger.WriteLine(cleanedFilepath + ": " + pairConfig.PairArray.Length + " pairs to sync");
                for (int i = 0; i < pairConfig.PairArray.Length; i++)
                {
                    Pair p = pairConfig.PairArray[i];
                    p.SourcePath = p.SourcePath.Replace("\\", "/").TrimEnd('/') + "/";
                    p.TargetPath = p.TargetPath.Replace("\\", "/").TrimEnd('/') + "/";

                    // if drive letter in path corresponds to a DriveConfig in the xml file, use the letter assigned to the label instead
                    string sourceDrive = Path.GetPathRoot(p.SourcePath);
                    if (sourceDrive.Length > 0 && OverrideDriveMapping.ContainsKey(sourceDrive[0]))
                    {
                        p.SourcePath = DriveMapping[OverrideDriveMapping[sourceDrive[0]]] + p.SourcePath.Substring(1);
                    }

                    string targetDrive = Path.GetPathRoot(p.TargetPath);
                    if (targetDrive.Length > 0 && OverrideDriveMapping.ContainsKey(targetDrive[0]))
                    {
                        p.TargetPath = DriveMapping[OverrideDriveMapping[targetDrive[0]]] + p.TargetPath.Substring(1);
                    }

                    Directory.CreateDirectory(p.TargetPath);
                    PairProcessor.SyncPair(p.SourcePath, p.TargetPath, p.FilterPattern, p.IgnoreList, comparisonMode, opts.ReportCount, opts.TimeResolution);
                }
            }
            ProgressReporter.Logger.Dispose();

            return(0);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sync a source folder with a target folder (backup)
        /// </summary>
        /// <param name="sourcePath">Path to the source folder</param>
        /// <param name="targetPath">Path to the target folder</param>
        /// <param name="filterPattern">Filter pattern for GetFiles</param>
        /// <param name="ignoreList">Files or folders to ignore</param>
        /// <param name="UseDate">Use last date of modification instead of hash</param>
        /// <param name="reportCount">Number of reports output to the console per section</param>
        public static void SyncPair(string sourcePath, string targetPath, string filterPattern, string[] ignoreList, Options.ComparisonMode comparisonMode, int reportCount = 100, float timeResolution = 0f)
        {
            if (sourcePath.Contains(targetPath) || targetPath.Contains(sourcePath))
            {
                throw new System.Exception("Paths between source and target MUST BE COMPLETELY DIFFERENT");
            }

            ProgressReporter.Logger.WriteLine("Starting syncing of pair " + sourcePath + " ---- " + targetPath);

            ProgressReporter.Logger.WriteLine("Computing directory differences");

            // Remove folders first in order to try to gain some execution time
            string[] TargetDirectoryList = Directory.GetDirectories(targetPath, "*", SearchOption.AllDirectories).Select(s => s.Replace("\\", "/").Replace(targetPath, "")).Where(s => !ignoreList.Any(w => s.Contains(w))).ToArray();
            string[] SourceDirectoryList = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories).Select(s => s.Replace("\\", "/").Replace(sourcePath, "")).Where(s => !ignoreList.Any(w => s.Contains(w))).ToArray();

            DeleteSourceOnlyDirectories(targetPath, reportCount, SourceDirectoryList, TargetDirectoryList);

            ProgressReporter.Logger.WriteLine("Computing file differences");
            FolderDiffBase folderDiff;

            switch (comparisonMode)
            {
            case Options.ComparisonMode.Date:
                folderDiff = new FolderDiffDate(sourcePath, targetPath, filterPattern, ignoreList, timeResolution);
                break;

            case Options.ComparisonMode.Binary:
                folderDiff = new FolderDiffBinary(sourcePath, targetPath, filterPattern, ignoreList);
                break;

            case Options.ComparisonMode.Hash:
                folderDiff = new FolderDiffHash(sourcePath, targetPath, filterPattern, ignoreList);
                break;

            default:
                throw new Exception("ComparisonMode " + comparisonMode.ToString() + " is not supported");
            }

            folderDiff.ComputeModifiedFilesList(reportCount);
            int errorCount = DeleteSourceOnlyFiles(folderDiff, reportCount);

            ProgressReporter progressReporter = new ProgressReporter(folderDiff);

            errorCount += AddSourceOnlyFiles(folderDiff, progressReporter, reportCount);
            errorCount += OverwriteModifiedFiles(folderDiff, progressReporter, reportCount);

            folderDiff.Dispose();

            ProgressReporter.Logger.WriteLine("Syncing of pair " + sourcePath + " ---- " + targetPath + " ---- Ended with " + errorCount + " errors");
        }