private void CopyInternal(string source, string destination, bool overwrite, bool nobuffering, Action <ProcessProgress> handler, ref int cancel) { try { mReportProgress = !handler.isNull(); if (mReportProgress) { System.IO.FileInfo info = new System.IO.FileInfo(source); mProgress = new ProcessProgress((int)info.Length, handler); mProgress.Text = destination; } CopyFileFlags copyFileFlags = CopyFileFlags.COPY_FILE_RESTARTABLE; if (!overwrite) { copyFileFlags |= CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS; } OperatingSystem os = Environment.OSVersion; if (nobuffering && os.Platform == PlatformID.Win32NT && os.Version.Major >= 6) { copyFileFlags |= CopyFileFlags.COPY_FILE_NO_BUFFERING; } mSource = source; mDestination = destination; bool result = CopyFileEx(mSource, mDestination, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref cancel, copyFileFlags); if (!result) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } catch (Exception ex) { // If the user canceled the copy we throw an exception, how nice is that. Just ignore it. if (ex.Message != "The request was aborted") { throw ex; } } if (mReportProgress) { if (cancel == 1) { mProgress.Canceled = true; } if (!mProgress.Canceled) { mProgress.Completed = true; } } }
public ProcessProgress(ProcessProgress aFileProgress) { if (aFileProgress == null) { init(); Total = 0; Processed = 0; } else { mTimer = new Timer(); mStopwatch = new Stopwatch(); Total = aFileProgress.Total; Processed = aFileProgress.Processed; Canceled = aFileProgress.Canceled; Notify = aFileProgress.Notify; } }
private static void CopyFileToMultipleDestinations(String source, IEnumerable <DestinationInfo> destinations, Action <ProcessProgress> handler, ref int cancel) { BufferedStream sourceStream = null; ProcessProgress progress = null; Exception exception = null; byte[] sourceBuffer = new byte[Constants.COPY_BUFFER_SIZE]; try { sourceStream = new BufferedStream(File.OpenRead(source)); progress = new ProcessProgress((int)sourceStream.Length, handler); foreach (DestinationInfo file in destinations) { FileExt.Create(file.Path, NameConflictOption.Overwrite); file.BufferStream = new BufferedStream(File.OpenWrite(file.Path)); } while (sourceStream.Position < sourceStream.Length) { if (cancel == 1) { progress.Canceled = true; break; } int streamLength = sourceStream.Read(sourceBuffer, 0, Constants.COPY_BUFFER_SIZE); foreach (DestinationInfo file in destinations) { file.BufferStream.Write(sourceBuffer, 0, streamLength); } progress.Processed = sourceStream.Position; } progress.Completed = true; } catch (Exception ex) { if (progress != null) { progress.Canceled = true; } exception = ex; } finally { foreach (DestinationInfo file in destinations) { if (file.BufferStream != null) { file.BufferStream.Close(); } } if (sourceStream != null) { sourceStream.Close(); } } if (exception != null) { throw exception; } }
/// <summary> /// Compares a source stream with multiple other files /// </summary> /// <param name="stream1">File stream for the source file</param> /// <param name="aFiles">List of files to compare</param> /// <returns>List of the results.</returns> private IEnumerable <ComparisonResult.Destination> CompareStreams(System.IO.Stream aSourceStream, IEnumerable <DestinationInfo> aFiles) { ProcessProgress progress = null; if (!HandleFileCompareProgress.isNull()) { progress = new ProcessProgress((int)aSourceStream.Length, (prog) => HandleFileCompareProgress(prog)); } else { progress = new ProcessProgress((int)aSourceStream.Length); } List <ComparisonResult.Destination> results = new List <ComparisonResult.Destination>(); const int bufferSize = 1024 * 1024 * 1;// 100; var buffer1 = new byte[bufferSize]; List <DestinationInfo> files = new List <DestinationInfo>(); foreach (DestinationInfo file in aFiles) { files.Add(file); file.Buffer = new byte[bufferSize]; } progress.Text = files[0].Path; uint hitCount = 0; bool done = false; while (!done && files.Count > 0) { if (mCancelRequested) { progress.Canceled = true; break; } int count1 = aSourceStream.Read(buffer1, 0, bufferSize); foreach (DestinationInfo file in files) { int count2 = file.BufferStream.Read(file.Buffer, 0, bufferSize); if (count1 != count2) { file.Result = new ComparisonResult.Destination(file.Path, ComparisonResult.DifferenceType.NotEqual); results.Add(file.Result); file.Done = true; files.Remove(file); } } if (count1 == 0) { done = true; } else { foreach (DestinationInfo file in files) { hitCount++; if (!UnsafeCompare(buffer1, file.Buffer)) { file.Result = new ComparisonResult.Destination(file.Path, ComparisonResult.DifferenceType.NotEqual); results.Add(file.Result); file.Done = true; files.Remove(file); } } } progress.Processed = aSourceStream.Position; } progress.Completed = true; return(results); }
/// <summary> /// Compare one source directory with multiple destination directories /// </summary> /// <param name="sourceDir">The source directory to compare</param> /// <param name="compareDir">The destination directories to compare</param> /// <param name="searchOption">If subdirectories should also be compared</param> /// <returns></returns> public List <ComparisonResult> CompareDirs(String sourceDir, IEnumerable <String> compareDirs, DirectorySearchOption searchOption) { List <DestinationInfo> directories = new List <DestinationInfo>(); IEnumerator <String> comparisonDirectory = compareDirs.GetEnumerator(); while (comparisonDirectory.MoveNext()) { directories.Add(new DestinationInfo(comparisonDirectory.Current)); } bool bailOut = false; List <ComparisonResult> results = new List <ComparisonResult>(); if (!Directory.Exists(sourceDir)) { ComparisonResult result = new ComparisonResult(sourceDir, sourceDir, ComparisonResult.DifferenceType.SourceMissing, false); results.Add(result); sendEvent(result); bailOut = true; } List <ComparisonResult.Destination> missingDestinationDirectoires = new List <ComparisonResult.Destination>(); foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { if (!Directory.Exists(dir.Path)) { missingDestinationDirectoires.Add(new ComparisonResult.Destination(dir.Path, ComparisonResult.DifferenceType.DestMissing)); dir.Done = true; } } if (missingDestinationDirectoires.Count > 0) { ComparisonResult compareResult = new ComparisonResult(sourceDir, missingDestinationDirectoires, false); sendEvent(compareResult); results.Add(compareResult); } if (bailOut || directories.All(d => d.Done)) { return(results); } // First compare all the files List <String> sourceFiles = DirectoryExt.GetFiles(sourceDir, searchOption); List <String> sourceDirs = DirectoryExt.GetDirectories(sourceDir, searchOption).ToList(); ProcessProgress progress = null; if (!HandleDirectoryCompareProgress.isNull()) { progress = new ProcessProgress(sourceFiles.Count + sourceDirs.Count, (prog) => HandleDirectoryCompareProgress(prog)); } else { progress = new ProcessProgress(sourceFiles.Count + sourceDirs.Count); } foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { dir.FileList = DirectoryExt.GetFiles(dir.Path, searchOption).ToList(); } for (int i = 0; i < sourceFiles.Count; ++i) { if (mCancelRequested) { break; } List <ComparisonResult.Destination> destinationResults = new List <ComparisonResult.Destination>(); String sourceFileName = sourceFiles[i]; List <String> filePaths = new List <string>(); foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { String destFileName = PathExt.Combine(dir.Path, PathExt.GetRelativePath(sourceDir, sourceFileName)); if (dir.FileList.Contains(destFileName)) { filePaths.Add(destFileName); dir.FileList.Remove(destFileName); } else { destinationResults.Add(new ComparisonResult.Destination(destFileName, ComparisonResult.DifferenceType.DestMissing)); } } progress.Processed++; ComparisonResult compareResult = CompareFiles(sourceFileName, filePaths); compareResult.Destinations.AddRange(destinationResults); if (compareResult.Destinations.Count > 0) { sendEvent(compareResult); results.Add(compareResult); } } foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { foreach (String file in dir.FileList) { if (mCancelRequested) { break; } ComparisonResult compareResult = new ComparisonResult(PathExt.Combine(sourceDir, PathExt.GetRelativePath(dir.Path, file)), file, ComparisonResult.DifferenceType.SourceMissing, true); sendEvent(compareResult); results.Add(compareResult); } } //Next compare the directories foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { if (mCancelRequested) { break; } dir.DirList = DirectoryExt.GetDirectories(dir.Path, searchOption).ToList(); } for (int i = 0; i < sourceDirs.Count; ++i) { foreach (DestinationInfo dir in directories.Where(d => !d.Done)) { if (mCancelRequested) { break; } String sourceDirName = sourceDirs[i]; String destDirName = PathExt.Combine(dir.Path, PathExt.GetRelativePath(sourceDir, sourceDirName)); if (dir.DirList.Contains(destDirName)) { dir.DirList.Remove(destDirName); } else { // Only send a difference if the directory is empty, otherwise the file comparison will cover this case. if (DirectoryExt.Empty(sourceDirName)) { ComparisonResult compareResult = new ComparisonResult(sourceDirName, destDirName, ComparisonResult.DifferenceType.DestMissing, false); sendEvent(compareResult); results.Add(compareResult); } } } progress.Processed++; } foreach (DestinationInfo directory in directories.Where(d => !d.Done)) { foreach (String dir in directory.DirList) { if (mCancelRequested) { break; } // Only send a difference if the directory is empty, otherwise the file comparison will cover this case. if (DirectoryExt.Empty(dir)) { ComparisonResult compareResult = new ComparisonResult(PathExt.Combine(sourceDir, PathExt.GetRelativePath(directory.Path, dir)), dir, ComparisonResult.DifferenceType.SourceMissing, false); sendEvent(compareResult); results.Add(compareResult); } } } if (mCancelRequested) { progress.Canceled = true; } progress.Completed = true; return(results); }