public void Save(Stream output, IProgress <ProgressReport> progress) { CheckDisposed(); using (var archiveStream = CreateTemporaryStream()) { using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true)) { BuildArchive(archive, progress); } // close archive archiveStream.Seek(0, SeekOrigin.Begin); CompressionUtility.Compress(archiveStream, output, progress); } // close archiveStream }
public void Save(string archivePath, IProgress <ProgressReport> progress) { CheckDisposed(); using (var archiveStream = CreateTemporaryStream()) { using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true)) { BuildArchive(archive, progress); } // close archive archiveStream.Seek(0, SeekOrigin.Begin); using (var lzmaStream = File.Create(archivePath)) { CompressionUtility.Compress(archiveStream, lzmaStream, progress); } } // close archiveStream }
public void Extract(string compressedArchivePath, string outputDirectory, IProgress <ProgressReport> progress) { using (var archiveStream = CreateTemporaryFileStream()) { // decompress the LZMA stream using (var lzmaStream = File.OpenRead(compressedArchivePath)) { CompressionUtility.Decompress(lzmaStream, archiveStream, progress); } var archivePath = ((FileStream)archiveStream).Name; // reset the uncompressed stream archiveStream.Seek(0, SeekOrigin.Begin); // read as a zip archive using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Read)) using (var tlArchive = new ThreadLocalZipArchive(archivePath, archive)) { List <ExtractOperation> extractOperations = new List <ExtractOperation>(); Dictionary <string, ExtractSource> sourceCache = new Dictionary <string, ExtractSource>(); // process the index to determine all extraction operations var indexEntry = archive.GetEntry(IndexFileName); using (var indexReader = new StreamReader(indexEntry.Open())) { Dictionary <string, ZipOperation> zipOperations = new Dictionary <string, ZipOperation>(StringComparer.OrdinalIgnoreCase); for (var line = indexReader.ReadLine(); line != null; line = indexReader.ReadLine()) { var lineParts = line.Split(pipeSeperator); if (lineParts.Length != 2) { throw new Exception("Unexpected index line format, too many '|'s."); } string target = lineParts[0]; string source = lineParts[1]; ExtractSource extractSource; if (!sourceCache.TryGetValue(source, out extractSource)) { sourceCache[source] = extractSource = new ExtractSource(source, _externalFiles, tlArchive); } var zipSeperatorIndex = target.IndexOf("::", StringComparison.OrdinalIgnoreCase); if (zipSeperatorIndex != -1) { string zipRelativePath = target.Substring(0, zipSeperatorIndex); string zipEntryName = target.Substring(zipSeperatorIndex + 2); string destinationPath = Path.Combine(outputDirectory, zipRelativePath); // operations on a zip file will be sequential ZipOperation currentZipOperation; if (!zipOperations.TryGetValue(destinationPath, out currentZipOperation)) { extractOperations.Add(currentZipOperation = new ZipOperation(destinationPath)); zipOperations.Add(destinationPath, currentZipOperation); } currentZipOperation.AddEntry(zipEntryName, extractSource); } else { string destinationPath = Path.Combine(outputDirectory, target); extractOperations.Add(new CopyOperation(extractSource, destinationPath)); } } } int opsExecuted = 0; // execute all operations //foreach(var extractOperation in extractOperations) extractOperations.AsParallel().ForAll(extractOperation => { extractOperation.DoOperation(); progress.Report(LocalizableStrings.Expanding, Interlocked.Increment(ref opsExecuted), extractOperations.Count); }); } } }