private void WriteCompressedBlock(FileStream outputFileStream, int blockNumber, byte[] compressedData) { var compressedBlock = new ArchiveBlock { BlockNumber = blockNumber, CompressedData = compressedData }; List <ArchiveBlock> buffer = null; lock (_writeToBufferLocker) { _buffer.Add(compressedBlock); _writtenBlocksAmount++; if (BufferIsFilled()) { buffer = _buffer; InitializeBuffer(); } } if (buffer != null) { WriteBufferToOutputFileStream(buffer, outputFileStream); } if (buffer == null && CurrentBlockIsLast()) { WriteBufferToOutputFileStream(_buffer, outputFileStream); } }
private long GetDecompressedBlockPosition(ArchiveBlock archiveBlock, FileStream outputFileStream) { long blockPosition = FormatConstants.BlockSize * archiveBlock.BlockNumber; if (blockPosition >= outputFileStream.Length) { throw new FormatException( $"Incorrect archive format. Block position {archiveBlock.BlockNumber} does not correspond to original file size = {outputFileStream.Length} bytes."); } return(blockPosition); }
private void FillBuffer(FileStream inputArchiveFileStream) { if (Monitor.TryEnter(_bufferFillingLocker)) { try { while (!_buffer.IsFull()) { var compressedDataBlockNumber = GetIntegerFromInputStream(inputArchiveFileStream); if (compressedDataBlockNumber == null) { _readingCompleted = true; return; } var compressedDataBlockSize = GetIntegerFromInputStream(inputArchiveFileStream); if (compressedDataBlockSize == null) { throw new FormatException( $"Incorrect archive format. Block with information about following compressed data block length should be {sizeof(int)} bytes size, but was 0 bytes."); } var compressedData = new byte[compressedDataBlockSize.Value]; var numberOfBytesRead = inputArchiveFileStream.Read(compressedData, 0, compressedDataBlockSize.Value); if (numberOfBytesRead != compressedDataBlockSize.Value) { throw new FormatException( $"Incorrect archive format. Block with compressed data block should be {compressedDataBlockSize.Value} bytes size, but was {numberOfBytesRead} bytes."); } var block = new ArchiveBlock { CompressedData = compressedData, BlockNumber = compressedDataBlockNumber.Value }; _buffer.Push(block); } } finally { Monitor.Exit(_bufferFillingLocker); } } }
private DecompressedArchiveBlockData DecompressBlock(ArchiveBlock archiveBlock) { var decompressedData = new byte[FormatConstants.BlockSize]; int numberOfBytesDecompressed; using (var memoryStream = new MemoryStream(archiveBlock.CompressedData)) { using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) { numberOfBytesDecompressed = gZipStream.Read(decompressedData, 0, FormatConstants.BlockSize); } } return(new DecompressedArchiveBlockData { DecompressedData = decompressedData, DecompressedDataLength = numberOfBytesDecompressed }); }