Ejemplo n.º 1
0
        /// <summary>
        /// Enumerates all files and directories from a given directory (PathTooLong safe, volume guid safe).
        /// </summary>
        public static WIN32_FILE[] GetEntries(string path, string searchPattern, SearchOption searchOption)
        {
            IEnumerable <WIN32_FILE> IEn  = EnumerateEntries(FixPath(path), searchPattern, searchOption);
            List <WIN32_FILE>        lTmp = new List <WIN32_FILE>(IEn);

            WIN32_FILE[] lEntries = new WIN32_FILE[lTmp.Count];
            lTmp.CopyTo(lEntries);

            return(lEntries);
        }
Ejemplo n.º 2
0
        // find all differences
        internal static bool Find(string sSourceRoot, string sDestRoot)
        {
            long          lTotalSize   = 0;                                                                             // total size of all processed files in bytes
            List <string> lErrorList   = new List <string>();                                                           // list of all errors which occured during process
            List <string> lFilesSource = new List <string>();                                                           // all relative file pathes from source drive (without drive)
            List <string> lDirsSource  = new List <string>();                                                           // all relative folder pathes from source drive (without drive)

            // get all entries on drive root (TopDirectoryOnly)
            // we have to skip volume specific folders here ($RECYCLE.BIN / System Volume Information)
            List <string>     lRootDirs = Directory.GetDirectories(sSourceRoot).Where(s => !s.EndsWith("$RECYCLE.BIN") && !s.EndsWith("System Volume Information")).ToList();
            List <WIN32_FILE> lEntries  = DLLS.GetEntriesList(sSourceRoot, "*", SearchOption.TopDirectoryOnly).Where(s => !s.Name.EndsWith("$RECYCLE.BIN") && !s.Name.EndsWith("System Volume Information")).ToList();

            // get all entries from root directories and append to entries list
            foreach (var sDir in lRootDirs)
            {
                lEntries.AddRange(DLLS.GetEntriesList(sDir, "*", SearchOption.AllDirectories));
            }

            // remove any duplicates?
            //var xEntries = new HashSet<WIN32_FILE>(lEntries);                                                         // HashSet is a lot faster than Distinct().ToList() when > 1*10^6 entries

            // copy entry list to WIN32_FILE array
            WIN32_FILE[] aSoureFiles = new WIN32_FILE[lEntries.Count];
            lEntries.CopyTo(aSoureFiles);
            lRootDirs.Clear();
            lEntries.Clear();                                                                                           // IMPORTANT: we will reuse lEntries as a temporary list

            Print("Found " + aSoureFiles.Length + " entries on source drive.");
            int iDirs  = 0;                                                                                             // count all directories
            int iFiles = 0;                                                                                             // count all files

            foreach (var SourceFile in aSoureFiles)
            {
                // handle directories
                if (SourceFile.isDirectory)
                {
                    iDirs++;
                    if (!lDirsSource.Contains(DLLS.GetPathDirs(SourceFile.FullPath)))
                    {
                        lDirsSource.Add(DLLS.GetPathDirs(SourceFile.FullPath));
                    }
                    continue;
                }

                iFiles++;
                lTotalSize += SourceFile.Size;                                                                          // add filesize to total size
                lFilesSource.Add(DLLS.GetPathDirs(SourceFile.FullPath));                                                // add full relative path from file

                string sDestPath = sDestRoot + DLLS.GetPathDirs(SourceFile.FullPath);                                   // create a hypothetically destination path for current file
                bool   bAdd      = false;                                                                               // should the file be synchronized?

                try
                {
                    // if file does not exist on destination drive (new file)
                    if (!DLLS.FileExists(sDestPath))
                    {
                        bAdd = true;
                    }

                    else if (!bOnlyNew)
                    {
                        WIN32_FILE DestFile = DLLS.GetFile(sDestPath);                                                  // get file infos

                        if (!bIgnoreSize)                                                                               // compare filesizes
                        {
                            if (SourceFile.Size != DestFile.Size)
                            {
                                bAdd = true;
                            }
                        }
                        if (!bIgnoreTime && !bAdd)                                                                      // compare last modification time
                        {
                            if (SourceFile.LastWriteTime != DestFile.LastWriteTime)
                            {
                                bAdd = true;
                            }
                        }
                        if (bCheckHash && !bAdd)                                                                        // calculate and compare checksums
                        {
                            string sSourceHash = DLLS.GetHashFromFile(SourceFile.FullPath, haChecksumAlgorithm);
                            string sDestHash   = DLLS.GetHashFromFile(DestFile.FullPath, haChecksumAlgorithm);

                            if (sSourceHash != sDestHash)
                            {
                                bAdd = true;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    lErrorList.Add(ex.Message);                                                                         // add any error to error list for now
                }

                // add file which will be synchronized to entries list (temporary)
                if (bAdd)
                {
                    lEntries.Add(SourceFile);
                    lSyncSize += SourceFile.Size;
                }
                UpdateProgress(iFiles + iDirs, aSoureFiles.Length);                                                     // show progress
            }

            Print("");
            Print("");

            // copy all file information which shall be synchronized to array
            FilesToSync = new WIN32_FILE[lEntries.Count];
            lEntries.CopyTo(FilesToSync);
            lEntries.Clear();

            // get all entries from destination drive
            lRootDirs = Directory.GetDirectories(sDestRoot).Where(s => !s.EndsWith("$RECYCLE.BIN") && !s.EndsWith("System Volume Information")).ToList();
            lEntries  = DLLS.GetEntriesList(sDestRoot, "*", SearchOption.TopDirectoryOnly).Where(s => !s.Name.EndsWith("$RECYCLE.BIN") && !s.Name.EndsWith("System Volume Information")).ToList();
            foreach (var sDir in lRootDirs)
            {
                lEntries.AddRange(DLLS.GetEntriesList(sDir, "*", SearchOption.AllDirectories));
            }

            WIN32_FILE[] aDestFiles = new WIN32_FILE[lEntries.Count];
            lEntries.CopyTo(aDestFiles);
            lEntries.Clear();
            lRootDirs.Clear();

            Print("Found " + aDestFiles.Length + " entries on destination drive.");

            foreach (var DestFile in aDestFiles)
            {
                // handle directories
                if (DestFile.isDirectory)
                {
                    // mark folder for deletation if relative path of destination dir is not present on source drive
                    if (!lDirsSource.Contains(DLLS.GetPathDirs(DestFile.FullPath)))
                    {
                        if (!lDirsToDelete.Contains(DestFile.FullPath))
                        {
                            lDirsToDelete.Add(DestFile.FullPath);                                                       // fill list with full path from destination drive
                        }
                    }
                    else
                    {
                        lDirsSource.Remove(DLLS.GetPathDirs(DestFile.FullPath));                                        // remove entry from source dir list so we can speed up future look up
                    }
                    continue;
                }

                // handle files
                if (!lFilesSource.Contains(DLLS.GetPathDirs(DestFile.FullPath)))
                {
                    lFilesToDelete.Add(DestFile.FullPath);                                                              // fill list with full path from destination drive
                }
                else
                {
                    lFilesSource.Remove(DLLS.GetPathDirs(DestFile.FullPath));                                           // remove entry from source file list so we can speed up future look up
                }
            }

            // print all errors
            if (lErrorList.Count > 0)
            {
                PrintError("ERROR: ");
                Logger("ERROR: ");
                foreach (var sErrorMsg in lErrorList)
                {
                    Print(sErrorMsg);
                    Logger(sErrorMsg);
                }
                Print("");
                Print("");
                Logger("");
            }
            Print("Processed " + iFiles + " files on source drive (" + String.Format("{0:0.00}", lTotalSize / 1073741824f) + " GiB)");
            Logger("Processed " + iFiles + " files on source drive (" + String.Format("{0:0.00}", lTotalSize / 1073741824f) + " GiB)");
            Print(FilesToSync.Length + " files to sync (" + String.Format("{0:0.00}", lSyncSize / 1073741824f) + " GiB)");
            Logger(FilesToSync.Length + " files to sync (" + String.Format("{0:0.00}", lSyncSize / 1073741824f) + " GiB)");
            Print(lFilesToDelete.Count + " files to delete on destination drive");
            Logger(lFilesToDelete.Count + " files to delete on destination drive");
            Print(lDirsToDelete.Count + " folders to delete on destination drive");
            Logger(lDirsToDelete.Count + " folders to delete on destination drive");

            // return result
            return(lErrorList.Count < 1);
        }