// метод сжатия архива private void Compress(FileStream Input, FileStream Output) { using (BinaryWriter BinaryWriter = new BinaryWriter(Output)) { // размер блока Int32 SourceSize = 1024 * 1024; // количество блоков Int32 BlocksCount = (Int32)(Input.Length / SourceSize) + (Input.Length % SourceSize != 0L ? 1 : 0); // запись количества блоков в файл BinaryWriter.Write(BlocksCount); // цикл по всем блокам for (Int32 Index = 0; Index < BlocksCount; ++Index) { // новый блок Block Block = new Block(); Block.SourceOffset = Index * SourceSize; Block.SourceSize = SourceSize; // новая задача Task <Block> Task = new Task <Block>(Block, (CurrentBlock) => { try { CurrentBlock.SourceData = new Byte[CurrentBlock.SourceSize]; // поиск и копирование блока в исходном файле lock (Input) { Input.Seek(CurrentBlock.SourceOffset, SeekOrigin.Begin); CurrentBlock.SourceSize = Input.Read(CurrentBlock.SourceData, 0, CurrentBlock.SourceSize); } CurrentBlock.Compress(); // запись сжатого блока и информации о нём CurrentBlock.CompressedOffset = Output.Position + CurrentBlock.SizeOfBlock; lock (Output) { BinaryWriter.Write(CurrentBlock.SourceOffset); BinaryWriter.Write(CurrentBlock.SourceSize); BinaryWriter.Write(CurrentBlock.CompressedOffset); BinaryWriter.Write(CurrentBlock.CompressedSize); Output.Write(CurrentBlock.CompressedData, 0, CurrentBlock.CompressedSize); } } catch (Exception E) { // ошибка - выход Console.WriteLine($"Внутренняя ошибка. {E.Message}"); Console.ReadKey(); Environment.Exit(1); } }); // добавляем задачу в менеджер потоков SmartThreadManager.Enqueue(Task); } // запускаем менеджер потоков SmartThreadManager.Start(); SmartThreadManager.Wait(); } }