public override Missing Handle(FileReplaceArguments arguments) { FileEntry sourceFile = ResolveExistingFile(arguments.SourcePath); AssertNoDuplicatePaths(arguments); AssertAllOnSameDrive(arguments); FileEntry destinationFile = ResolveExistingFile(arguments.DestinationPath); bool destinationHasOnlyArchiveAttribute = destinationFile.Attributes == FileAttributes.Archive; NotifySourceFileChanged(sourceFile, destinationFile); NotifyDirectoriesChanged(false, destinationFile.Parent, sourceFile.Parent); BackupFileInfo backupFileInfo = BackupFileInfo.FromPath(arguments.BackupDestinationPath, Container); if (backupFileInfo != null && !backupFileInfo.Exists) { string destinationFileName = destinationFile.Name; DirectoryEntry destinationDirectory = destinationFile.Parent; MoveSingleFile(destinationFile, backupFileInfo.Directory, backupFileInfo.FileName, destinationFile.PathFormatter, false); if (destinationDirectory != backupFileInfo.Directory) { NotifyDirectoriesChanged(false, destinationDirectory); } FileEntry backupFile = backupFileInfo.GetExistingFile(); TransferSourceContentsToDestinationFile(sourceFile, destinationDirectory, destinationFileName, backupFile); } else { var spaceTracker = new VolumeSpaceTracker(sourceFile.Parent.Root); if (backupFileInfo == null) { FileEntry tempBackupFile = CreateTempBackupFile(destinationFile); NotifyDirectoriesChanged(false, tempBackupFile.Parent); backupFileInfo = BackupFileInfo.FromTempFile(tempBackupFile, Container); } FileEntry backupFile = backupFileInfo.GetExistingFile(); if (backupFile.Parent != destinationFile.Parent && backupFile.Parent != sourceFile.Parent) { NotifyDirectoriesChanged(false, backupFile.Parent); } TransferDestinationContentsToExistingBackupFile(destinationFile, backupFile, spaceTracker); destinationFile.Parent.DeleteFile(destinationFile.Name, true); Container.ChangeTracker.NotifyContentsAccessed(backupFile.PathFormatter, FileAccessKinds.All); NotifyDirectoriesChanged(backupFileInfo.IsTempFile, backupFile.Parent, destinationFile.Parent); TransferSourceContentsToDestinationFile(sourceFile, destinationFile.Parent, destinationFile.Name, destinationFile); spaceTracker.ApplyVolumeSpaceChange(); } backupFileInfo.Complete(); if (!destinationHasOnlyArchiveAttribute) { Container.ChangeTracker.NotifyContentsAccessed(backupFileInfo.Path.Formatter, FileAccessKinds.Attributes); Container.ChangeTracker.NotifyContentsAccessed(arguments.DestinationPath.Formatter, FileAccessKinds.Attributes); } return(Missing.Value); }
private void TransferDestinationContentsToExistingBackupFile([NotNull] FileEntry destinationFile, [NotNull] FileEntry backupFile, [NotNull] VolumeSpaceTracker spaceTracker) { AssertBackupFileIsNotReadOnly(backupFile); AssertHasExclusiveAccessToBackupFile(backupFile); spaceTracker.SetBackupFileSizeChange(destinationFile.Size - backupFile.Size); backupFile.TransferFrom(destinationFile); }