private void CompressWrite(FileStream destinationStream) { do { DataBlock outcomingBlock = writeBuffer.GetBlock(); if (outcomingBlock == null) { //Если поток запросит блок раньше, чем появились готовые блоки continue; } if (outcomingBlock.Id != lastWritedBlockId + 1) { //очередность блоков (Если какой-нибудь поток обработал следующий блок раньше предыдущего) continue; } //записать длину блока BitConverter.GetBytes(outcomingBlock.Data.Length).CopyTo(outcomingBlock.Data, 4); //byte[] buffer = outcomingBlock.Data; //BitConverter.GetBytes(buffer.Length).CopyTo(buffer, 4); destinationStream.Write(outcomingBlock.Data, 0, outcomingBlock.Data.Length); lastWritedBlockId = outcomingBlock.Id; writeBuffer.DeleteBlock(outcomingBlock.Id); BlockWritedInfo(outcomingBlock); } while (!isTerminated && (reader.IsWorking() || reader.BlocksRead() > lastWritedBlockId || writeBuffer.GetCurrentBlocksCount() > 0)); }
protected override void Write() { try { using (FileStream destinationStream = new FileStream($"{destinationFileName}.gz", FileMode.Append, FileAccess.Write, FileShare.None)) { do { DataBlock outcomingBlock = writeBuffer.GetBlock(); if (outcomingBlock == null) { //Если поток запросит блок раньше, чем появились готовые блоки // TODO: подумать как обойти continue; } if (outcomingBlock.Id != lastWritedBlockId + 1) { //очередность блоков (Если какой-нибудь поток обработал следующий блок раньше предыдущего) continue; } BitConverter.GetBytes(outcomingBlock.Data.Length).CopyTo(outcomingBlock.Data, 4); byte[] buffer = outcomingBlock.Data; BitConverter.GetBytes(buffer.Length).CopyTo(buffer, 4); destinationStream.Write(buffer, 0, buffer.Length); //destinationStream.Write(outcomingBlock.Data, 0, outcomingBlock.Data.Length); lastWritedBlockId = outcomingBlock.Id; writeBuffer.DeleteBlock(outcomingBlock.Id); if (needProcessInfo) { Console.WriteLine("Block {0} writed by thread {1}, id {2}", outcomingBlock.Id, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId); } } while (!isTerminated && (reader.IsWorking() || reader.BlocksRead() > lastWritedBlockId || writeBuffer.GetCurrentBlocksCount() > 0)); if (needProcessInfo) { Console.WriteLine("Thread {0} finish work", Thread.CurrentThread.Name); } } } catch (Exception ex) { Console.WriteLine(ex.Message); isTerminated = hasErrors = true; } finally { waitEndOfWriteHandle.Set(); } }