private async Task DecompressFileAsync(FileHeader fileHeader) { await using var outputStream = ArchiveStream.Create(fileHeader.FullPath); var chunkDecompressor = GetChunkDecompressor(fileHeader.IsEncrypted); foreach (var chunk in fileHeader.Chunks) { byte[] compressChunk; using (await _asyncLock.LockAsync()) { _inputStream.Position = fileHeader.Position; compressChunk = await _inputStream.ReadBytesAsync(chunk.Size); } fileHeader.Position += chunk.Size; try { await chunkDecompressor(compressChunk, outputStream, fileHeader.CompressionType); } catch { if (fileHeader.IsEncrypted) { throw new ArchiveException(ExceptionResource.InvalidEncryptKey); } throw new ArchiveException(ExceptionResource.ThisFileIsCorrupted); } _archiveProgress.Report(fileHeader.RelativePath, chunk.Size, chunk.SerialNumber, fileHeader.NumberOfChunks); } }
public async Task CreateAsync(string inputPath, string outputPath) { await using var outputStream = ArchiveStream.Create(outputPath); var metadata = new Metadata.Metadata(inputPath); var directoryHeaders = await metadata.GenerateDirectoryHeadersAsync(); var fileHeaders = await metadata.GenerateFileHeadersAsync(); var archiveInfo = new ArchiveInfo() { Header = ArchiveResource.ArchiveHeader, IsEncrypted = Compressor.Settings.IsEncryptEnable, NumberOfDirectories = directoryHeaders.Count, NumberOfFiles = fileHeaders.Count, }; archiveInfo.DirectoriesBlockPosition = archiveInfo.SizeOf; outputStream.Seek(archiveInfo.SizeOf, SeekOrigin.Current); await outputStream.WriteDirectoriesAsync(directoryHeaders); archiveInfo.FilesBlockPosition = outputStream.Position; await outputStream.WriteArchiveInfoAsync(archiveInfo); outputStream.Position = archiveInfo.FilesBlockPosition; await Compressor.CompressAsync(fileHeaders, outputStream); }