/// <summary> /// Processes a file that has a delta update /// </summary> /// <param name="tempFolder">Where the temp folder is located</param> /// <param name="originalFile">Where the original file is</param> /// <param name="newFile">Where the updated file should be placed on disk</param> /// <param name="file">Details about the update</param> /// <param name="progress">Progress for applying the update</param> /// <returns>If the file was successfully updated</returns> public static async Task <bool> ProcessDeltaFile(TemporaryFolder tempFolder, string originalFile, string newFile, FileEntry file, Action <double>?progress = null) { if (file.Stream == null) { Logger.Warning("{0} was updated but we don't have the delta stream for it!", file.Filename); return(false); } Logger.Debug("File was updated, applying delta update"); var deltaUpdater = DeltaUpdaters.GetUpdater(file.DeltaExtension); if (deltaUpdater != null) { return(await deltaUpdater.ApplyDeltaFile(tempFolder, originalFile, newFile, file.Filename, file.Stream, progress)); } Logger.Error("Wasn't able to find what was responsible for creating this diff file (File: {0}, Extension: {1})", file.Filename, file.DeltaExtension); return(false); }
/// <summary> /// Creates a delta file by going through the different ways of creating delta files and grabbing the one that made the smallest file /// </summary> /// <param name="tempFolder">Where the temp folder is located</param> /// <param name="baseFileLocation">Where the older version of the file exists</param> /// <param name="newFileLocation">Where the newer version of the file exists</param> /// <param name="deltaFileLocation">Where the delta file should be stored (If we are unable to store it in a stream)</param> /// <param name="intendedOs">What OS this delta file will be intended for</param> /// <param name="extension">Extension of the delta file</param> /// <param name="deltaFileStream">The contents of the delta file</param> /// <param name="progress">Progress of making the delta file (If we can report the progress back)</param> public static bool CreateDeltaFile( TemporaryFolder tempFolder, string baseFileLocation, string newFileLocation, string deltaFileLocation, OSPlatform?intendedOs, out string extension, out Stream?deltaFileStream, Action <double>?progress = null) { var os = intendedOs ?? OSHelper.ActiveOS; IReadOnlyList <IDeltaUpdate>?deltaUpdaters = null; lock (_updaterLock) { if (CachedUpdaters.ContainsKey(os)) { deltaUpdaters = CachedUpdaters[os]; } else { deltaUpdaters ??= DeltaUpdaters.GetUpdatersBasedOnOS(intendedOs ?? OSHelper.ActiveOS); CachedUpdaters.Add(os, deltaUpdaters); } } var updaterCount = deltaUpdaters.Count; var progresses = new double[updaterCount]; var deltaResults = new List <DeltaCreationResult>(updaterCount); Parallel.For(0, updaterCount, i => { var deltaUpdater = deltaUpdaters[i]; var deltaFile = tempFolder.CreateTemporaryFile(); var successful = deltaUpdater.CreateDeltaFile( tempFolder, baseFileLocation, newFileLocation, deltaFile.Location, out var stream, pro => { progresses[i] = pro; progress?.Invoke(progresses.Sum() / updaterCount); }); if (successful) { deltaResults.Add( new DeltaCreationResult(deltaUpdater.Extension, deltaFile, stream)); } else { Logging.Warning("{0} was unable to make a delta file for {1}", nameof(deltaUpdater), baseFileLocation.GetRelativePath(newFileLocation)); deltaFile.Dispose(); } if (progresses[i] < 1d) { progresses[i] = 1d; progress?.Invoke(progresses.Sum() / updaterCount); } });