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 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); } }
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++; } }