private bool ApplyDiffToFile(string filePath, string diffPath, string targetPath, int patchItemIndex) { PatchItem item = patchInfo.Files[patchItemIndex]; FileInfo targetFile = new FileInfo(targetPath); if (targetFile.Exists && targetFile.MatchesSignature(item.AfterFileSize, item.AfterMd5Hash)) { comms.Log(Localization.Get(StringId.AlreadyUpToDateXthFile, patchItemIndex + 1, patchInfo.Files.Count, item.Path)); return(true); } if (item.BeforeFileSize == 0L) { comms.Log(Localization.Get(StringId.CreatingXthFile, patchItemIndex + 1, patchInfo.Files.Count, item.Path)); Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); PatchUtils.CopyFile(diffPath, targetPath); File.Delete(diffPath); return(true); } FileInfo localFile = new FileInfo(filePath); if (!localFile.Exists || !localFile.MatchesSignature(item.BeforeFileSize, item.BeforeMd5Hash)) { return(false); } comms.Log(Localization.Get(StringId.UpdatingXthFile, patchItemIndex + 1, patchInfo.Files.Count, item.Path)); FilePatchProgress progress = null; string tempOutputPath = diffPath + "_.tmp"; if (comms.LogProgress) { progress = new FilePatchProgress(comms, Path.GetFileName(filePath)); } OctoUtils.ApplyDelta(filePath, tempOutputPath, diffPath, progress); FileInfo updatedFile = new FileInfo(tempOutputPath); if (!updatedFile.Exists || !updatedFile.MatchesSignature(item.AfterFileSize, item.AfterMd5Hash)) { return(false); } Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); PatchUtils.CopyFile(tempOutputPath, targetPath); File.Delete(tempOutputPath); File.Delete(diffPath); return(true); }
public static void CalculateDelta(string sourcePath, string targetPath, string deltaPath, FilePatchProgress progressReporter = null) { using (var signatureStream = new MemoryStream()) { using (var basisStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { new SignatureBuilder().Build(basisStream, new SignatureWriter(signatureStream)); } signatureStream.Position = 0L; using (var newFileStream = new FileStream(targetPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var deltaStream = new FileStream(deltaPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { IProgressReporter reporter = progressReporter; if (reporter == null) { reporter = new NullProgressReporter(); } new DeltaBuilder().BuildDelta(newFileStream, new SignatureReader(signatureStream, reporter), new AggregateCopyOperationsDecorator(new BinaryDeltaWriter(deltaStream))); } } }
public static void ApplyDelta(string sourcePath, string targetPath, string deltaPath, FilePatchProgress progressReporter = null) { using (var basisStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var deltaStream = new FileStream(deltaPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var newFileStream = new FileStream(targetPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { IProgressReporter reporter = progressReporter; if (reporter == null) { reporter = new NullProgressReporter(); } new DeltaApplier().Apply(basisStream, new BinaryDeltaReader(deltaStream, reporter), newFileStream); } }
public static void CalculateDelta(string sourcePath, string targetPath, string deltaPath, int quality = 3, FilePatchProgress progressReporter = null) { // Try different chunk sizes to find the smallest diff file if (quality < 1) { quality = 1; } int[] chunkSizes = new int[quality * 2 - 1]; chunkSizes[0] = SignatureBuilder.DefaultChunkSize; int validChunkSizes = 1; int currentChunkSize = chunkSizes[0]; for (int i = 1; i < quality; i++) { currentChunkSize /= 2; if (currentChunkSize < SignatureBuilder.MinimumChunkSize) { break; } chunkSizes[validChunkSizes++] = currentChunkSize; } currentChunkSize = chunkSizes[0]; for (int i = 1; i < quality; i++) { currentChunkSize *= 2; if (currentChunkSize > SignatureBuilder.MaximumChunkSize) { break; } chunkSizes[validChunkSizes++] = currentChunkSize; } string deltaPathTemp = deltaPath + ".detmp"; string signaturePathTemp = deltaPath + ".sgtmp"; long deltaSize = 0L; for (int i = 0; i < validChunkSizes; i++) { if (i == 0) { CalculateDeltaInternal(sourcePath, targetPath, deltaPath, signaturePathTemp, chunkSizes[i], progressReporter); deltaSize = new FileInfo(deltaPath).Length; } else { CalculateDeltaInternal(sourcePath, targetPath, deltaPathTemp, signaturePathTemp, chunkSizes[i], progressReporter); long newDeltaSize = new FileInfo(deltaPathTemp).Length; if (newDeltaSize < deltaSize) { PatchUtils.MoveFile(deltaPathTemp, deltaPath); deltaSize = newDeltaSize; } } } File.Delete(deltaPathTemp); File.Delete(signaturePathTemp); }