private void WriteHeader(BlocksQueue writeQueue, string outputFile) { using (var outStream = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write)) using (var binaryWriter = new BinaryWriter(outStream)) { binaryWriter.Write(writeQueue.TotalBlocksCount); _witeHeaderOffset += sizeof(int); _writeDataOffset += (writeQueue.TotalBlocksCount * 2 + 1) * sizeof(int); } }
protected override BlocksQueue GetReadQueue(string path) { using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var reader = new BinaryReader(file)) { var blocksCount = reader.ReadInt32(); var readQueue = new BlocksQueue(blocksCount); var readOffset = (blocksCount * 2 + 1) * sizeof(int); for (int i = 0; i < blocksCount; ++i) { var size = reader.ReadInt32(); var writeOffset = reader.ReadInt32(); readQueue.PushBlock(new FileBlock(size, readOffset, writeOffset)); readOffset += size; } return(readQueue); } }
protected override BlocksQueue GetReadQueue(string path) { var fileInfo = new FileInfo(path); double fileSize = fileInfo.Length / (_blockSize * 1f); var blocksCount = (int)Math.Ceiling(fileSize); var blocksQueue = new BlocksQueue(blocksCount); for (int i = 0; i < blocksCount - 1; ++i) { blocksQueue.PushBlock(new FileBlock(_blockSize, i * _blockSize)); } var size = (int)(fileInfo.Length - (blocksCount - 1) * _blockSize); var offset = (blocksCount - 1) * _blockSize; blocksQueue.PushBlock(new FileBlock(size, offset)); return(blocksQueue); }
protected override void Write(BlocksQueue writeQueue, string outputFile) { WriteHeader(writeQueue, outputFile); while (writeQueue.PreparedBlocks < writeQueue.TotalBlocksCount && !writeQueue.IsStoped) { try { var block = writeQueue.PopBlock(); WriteBlock(outputFile, block); writeQueue.PreparedBlocks++; } catch (Exception e) { writeQueue.Stop(); _logger.Error(e, "An error occurred while writing block of compressed file"); } } _logger.Info(string.Format("File compressed")); }
private void Decompress(string filename, string outputFile) { var readQueue = GetReadQueue(filename); var writeQueue = new BlocksQueue(readQueue.TotalBlocksCount); var writerThread = new Thread(() => { Write(writeQueue, outputFile); }); writerThread.Start(); var maxThreadForRead = _maxThreadCount - 1; var semaphore = new Semaphore(maxThreadForRead, maxThreadForRead); while (readQueue.PreparedBlocks < readQueue.TotalBlocksCount && !readQueue.IsStoped && semaphore.WaitOne()) { var readThread = new Thread(() => { var block = readQueue.PopBlock(); ReadBlock(filename, block); if (block.HasError) { readQueue.Stop(); writeQueue.Stop(); } else { writeQueue.PushBlock(block); } semaphore.Release(); }); readThread.Start(); readQueue.PreparedBlocks++; } }
protected abstract void Write(BlocksQueue writeQueue, string outputFile);