private static async Task ExtractArchiveSync(string headerFile, string dataFile, string destinationPath) { using (MS2Archive archive = await MS2Archive.Load(headerFile, dataFile).ConfigureAwait(false)) { List <MS2File> files = archive.Files; for (int i = 0; i < files.Count; i++) { MS2File file = files[i]; Logger.Info($"Extracting file \"{file.Name}\", \"{FileEx.FormatStorage(file.Header.Size)}\". ({file.Header.Id}/{files.Count})"); await ExtractFileAsync(destinationPath, file).ConfigureAwait(false); } } }
private static async Task ExtractFileAsync(string destinationPath, MS2File file) { if (String.IsNullOrWhiteSpace(file.Name)) { Logger.Warning($"File number \"{file.Id}\", \"{FileEx.FormatStorage(file.Header.Size)}\" has no name and will be ignored."); return; } string fileDestinationPath = Path.Combine(destinationPath, file.Name); (Stream stream, bool shouldDispose) = await file.GetDecryptedStreamAsync().ConfigureAwait(false); try { await stream.CopyToAsync(fileDestinationPath).ConfigureAwait(false); } finally { if (shouldDispose) { stream.Dispose(); } } }
internal static async Task <MS2File> Load(MS2CryptoMode cryptoMode, Stream headerStream, Stream dataStream, MemoryMappedFile dataMemoryMappedFile) { MS2FileInfoHeader fileInfoHeader = await MS2FileInfoHeader.Load(headerStream).ConfigureAwait(false); MS2FileHeader fileHeader = await MS2FileHeader.Load(cryptoMode, dataStream).ConfigureAwait(false); DLogger.Write($"Id={fileInfoHeader.Id}-{fileHeader.Id}, CompressionId={fileHeader.CompressionType}, RootFolder={fileInfoHeader.RootFolderId}, Name={fileInfoHeader.Name}, Size={FileEx.FormatStorage(fileHeader.EncodedSize)}->{FileEx.FormatStorage(fileHeader.CompressedSize)}->{FileEx.FormatStorage(fileHeader.Size)}"); var file = new MS2File(fileInfoHeader, fileHeader, cryptoMode, dataMemoryMappedFile); return(file); }