Example #1
0
        /// <summary>
        /// Similar to CopyFile, but engineered for large (>1GB) files, as it
        /// uses a copy marker
        /// </summary>
        public static void CopyLargeFile
        (
            FileInfo sourceFile,
            FileInfo targetFile,
            CollisionRemediation cr)
        {
            // TODO Pri 2 (Perf): Use PowerShell to do the copy directly if sender
            // and receiver machines are not the current machine

            Debug.Assert(sourceFile != null);

            Common.WriteLine
            (
                "BEGIN Copying {0} to {1}",
                sourceFile.FullName,
                targetFile.FullName
            );

            if (File.Exists(targetFile.FullName + Constants.COPY_MARKER))
            {
                Common.WriteVerboseLine
                (
                    "Deleting existing transfer artifact {0}",
                    targetFile.FullName + Constants.COPY_MARKER
                );

                File.Delete(targetFile.FullName + Constants.COPY_MARKER);
            }

            Boolean bail    = false;
            Boolean throwex = false;
            Boolean proceed = true;

            if (targetFile.Exists)
            {
                proceed = false;

                switch (cr)
                {
                case CollisionRemediation.Break:
                case CollisionRemediation.Passive:
                case CollisionRemediation.FillIn:
                    Common.WriteLine("Target file exists, exiting");
                    bail = true;
                    break;

                case CollisionRemediation.Mirror:
                    if (FileCompare.AreSameBinaryViaFullScan(sourceFile, targetFile))                                // TODO Pri 2 (Perf): Avoid full scan?
                    {
                        Common.WriteLine("Target file already exists (and is identical), exiting");
                    }
                    else
                    {
                        Common.WriteLine("Target file exists, but is different: deleting");
                        File.Delete(targetFile.FullName);
                        proceed = true;
                    }
                    break;

                case CollisionRemediation.Overwrite:
                    Common.WriteLine("Target file exists, deleting");
                    File.Delete(targetFile.FullName);
                    proceed = true;
                    break;

                case CollisionRemediation.Throw:
                    throwex = true;
                    break;
                }
            }

            if (throwex)
            {
                throw new ScarabException("Target file '{0}' already exists", targetFile.FullName);
            }
            else if (proceed)
            {
                Common.WriteVerboseLine
                (
                    "Copying {0} to {1}",
                    sourceFile.FullName,
                    targetFile.FullName + Constants.COPY_MARKER
                );

                // E.g., to \\Path\LARGE_FILE_TEMPLATE.vhd.transferring
                sourceFile.CopyTo(targetFile.FullName + Constants.COPY_MARKER);

                Common.WriteVerboseLine
                (
                    "Renaming {0} to {1}",
                    targetFile.FullName + Constants.COPY_MARKER,
                    targetFile.FullName
                );

                File.Move(targetFile.FullName + Constants.COPY_MARKER, targetFile.FullName);

                Common.WriteLine
                (
                    "COMPLETE Copying {0} to {1}",
                    sourceFile.FullName,
                    targetFile.FullName
                );
            }
            else if (bail)
            {
            }
        }
Example #2
0
        /// <summary>
        /// Copies a single file
        /// </summary>
        /// <param name="sourceFile">Source directory node</param>
        /// <param name="targetFile">Directory node to where the source directory tree should be copied</param>
        /// <param name="cr">How to handle collisions</param>
        /// <param name="deleteSourceFile">Remove source file (a.k.a. MOVE)</param>
        private static void CopyFileWorker
        (
            string sourceFilePath,
            string targetFilePath,
            CollisionRemediation cr)
        {
            Debug.Assert(sourceFilePath != null);
            Debug.Assert(targetFilePath != null);

            Common.WriteVerboseLine
            (
                "--> FileSync.CopyFile: {0} {1} {2}",
                sourceFilePath,
                targetFilePath,
                cr.ToString()
            );

            //string switches = "/F /Z /V ";
            Boolean throwEx = false;

            /*
             * XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
             *                                                 [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
             *                                                 [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B] [/J]
             *                                                 [/EXCLUDE:file1[+file2][+file3]...]
             * source       Specifies the file(s) to copy.
             * destination  Specifies the location and/or name of new files.
             * /A           Copies only files with the archive attribute set,
             *                         doesn't change the attribute.
             * /M           Copies only files with the archive attribute set,
             *                         turns off the archive attribute.
             * /D:m-d-y     Copies files changed on or after the specified date.
             *                         If no date is given, copies only those files whose
             *                         source time is newer than the destination time.
             * /EXCLUDE:file1[+file2][+file3]...
             *                         Specifies a list of files containing strings.  Each string
             *                         should be in a separate line in the files.  When any of the
             *                         strings match any part of the absolute path of the file to be
             *                         copied, that file will be excluded from being copied.  For
             *                         example, specifying a string like \obj\ or .obj will exclude
             *                         all files underneath the directory obj or all files with the
             *                         .obj extension respectively.
             * /P           Prompts you before creating each destination file.
             * /S           Copies directories and subdirectories except empty ones.
             * /E           Copies directories and subdirectories, including empty ones.
             *                         Same as /S /E. May be used to modify /T.
             * /V           Verifies the size of each new file.
             * /W           Prompts you to press a key before copying.
             * /C           Continues copying even if errors occur.
             * /I           If destination does not exist and copying more than one file,
             *                         assumes that destination must be a directory.
             * /Q           Does not display file names while copying.
             * /F           Displays full source and destination file names while copying.
             * /L           Displays files that would be copied.
             * /G           Allows the copying of encrypted files to destination that does not support encryption.
             * /H           Copies hidden and system files also.
             * /R           Overwrites read-only files.
             * /T           Creates directory structure, but does not copy files. Does not
             *                         include empty directories or subdirectories. /T /E includes
             *                         empty directories and subdirectories.
             * /U           Copies only files that already exist in destination.
             * /K           Copies attributes. Normal Xcopy will reset read-only attributes.
             * /N           Copies using the generated Int16 names.
             * /O           Copies file ownership and ACL information.
             * /X           Copies file audit settings (implies /O).
             * /Y           Suppresses prompting to confirm you want to overwrite an existing destination file.
             * /-Y          Causes prompting to confirm you want to overwrite an existing destination file.
             * /Z           Copies networked files in restartable mode.
             * /B           Copies the Symbolic Link itself versus the target of the link.
             * /J           Copies using unbuffered I/O. Recommended for very large files.
             *
             * The switch /Y may be preset in the COPYCMD environment variable.
             * This may be overridden with /-Y on the command line.
             */

            Boolean proceed = true;

            if (File.Exists(targetFilePath))
            {
                proceed = false;

                switch (cr)
                {
                case CollisionRemediation.Break:
                case CollisionRemediation.Passive:
                case CollisionRemediation.FillIn:
                    Common.WriteLine("Target file exists, exiting");
                    break;

                case CollisionRemediation.Mirror:
                    if (FileCompare.AreSameBinaryViaFullScan
                        (
                            new FileInfo(sourceFilePath),
                            new FileInfo(targetFilePath)))                                 // TODO Pri 1: FASTER
                    {
                        Common.WriteLine("Target file already exists (and is identical), exiting");
                    }
                    else
                    {
                        Common.WriteLine("Target file exists, but is different: deleting");
                        File.Delete(targetFilePath);
                        proceed = true;
                    }
                    break;

                case CollisionRemediation.Overwrite:
                    Common.WriteLine("Target file exists, deleting");
                    File.Delete(targetFilePath);
                    proceed = true;
                    break;

                case CollisionRemediation.Throw:
                    throwEx = true;
                    break;
                }
            }

            if (throwEx)
            {
                throw new ScarabException("Target file '{0}' already exists", targetFilePath);
            }

            if (proceed)
            {
                File.Copy(sourceFilePath, targetFilePath);
            }
        }
Example #3
0
		/// <summary>
		/// Returns true if the directories have the same content, false otherwise
		/// </summary>
		/// <param name="directory1"></param>
		/// <param name="directory2"></param>
		/// <param name="verbose">Whether to print to the command line</param>
		/// <returns></returns>
		public static Boolean AreSame( DirectoryInfo directory1, DirectoryInfo directory2, Boolean verbose )
		{
			if( !Directory.Exists( directory1.FullName ) )
			{
				if( verbose )
				{
					Console.WriteLine( "--> Directory {0} does not exist, comparison failed", directory1.FullName );
				};
				return false;
			}

			if( !Directory.Exists( directory2.FullName ) )
			{
				if( verbose )
				{
					Console.WriteLine( "--> Directory {0} does not exist, comparison failed", directory2.FullName );
				};
				return false;
			}

			// Take a snapshot of the file system
			IEnumerable<System.IO.FileInfo> list1 = directory1.GetFiles( "*.*", System.IO.SearchOption.AllDirectories );
			IEnumerable<System.IO.FileInfo> list2 = directory2.GetFiles( "*.*", System.IO.SearchOption.AllDirectories );

			//A custom file comparer defined below
			FileCompare myFileCompare = new FileCompare();

			// This query determines whether the two folders contain
			// identical file lists, based on the custom file comparer
			// that is defined in the FileCompare class.
			// The query executes immediately because it returns a Boolean.
			Boolean areIdentical = list1.SequenceEqual( list2, myFileCompare );

			if( areIdentical == true )
			{
				fr.Common.WriteVerboseLine
				(
					"Directories '{0}' and '{1}' are identical",
					directory1.FullName,
					directory2.FullName
				);
			}
			else
			{
				if( verbose )
				{
					Console.WriteLine( "--------------------------------------------" );
					fr.Common.WriteVerboseLine( "Directories not the same.  Files:" );
					Console.WriteLine();
					// Find the common files. It produces a sequence and doesn't
					// execute until the foreach statement.
					var queryCommonFiles = list1.Intersect( list2, myFileCompare );

					Console.WriteLine( "--> In both folders:" );
					foreach( var v in queryCommonFiles )
					{
						Console.WriteLine( "    {0}", v.FullName ); //shows which items end up in result list
					}
					Console.WriteLine();

					// Find the set difference between the two folders.
					var queryList1Only = ( from file in list1
										   select file ).Except( list2, myFileCompare );

					Console.WriteLine( "--> Only in {0}:", directory1.FullName );
					foreach( var v in queryList1Only )
					{
						Console.WriteLine( "    {0}", v.FullName );
					}
					Console.WriteLine();

					var queryList2Only = ( from file in list2
										   select file ).Except( list1, myFileCompare );

					Console.WriteLine( "--> The following files are only in {0}:", directory2.FullName );
					foreach( var v in queryList2Only )
					{
						Console.WriteLine( "    {0}", v.FullName );
					}
					Console.WriteLine( "--------------------------------------------" );
				}
			}

			return areIdentical;
		}