示例#1
0
        // метод сжатия архива
        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();
            }
        }