Пример #1
0
        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);
        }
Пример #2
0
        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)));
                    }
            }
        }
Пример #3
0
        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);
                    }
        }
Пример #4
0
        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);
        }