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);
            }
        }
示例#2
0
        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);
        }