GZipstream - каков принцип многопоточного сжатия/распаковки? - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день! Интересует тема сходная с Организация многопоточности. Организовал многопоточное сжатие, никаких конфликтов, а вот как распаковать сие чудо не пойму! Делаю так (Сжатие): 1.Читаю файл массивами блоков (массив по количеству процессов) 2.Архивация потоками 3.Полученный сжатый массив пишу в файл 4.Читаем следующий массив и т.д. Вот в чём интересность - сжатие происходит без ошибок, распаковка делается даже Winrarом, но КАК мне реализовать распаковку самому? Ведь, когда пишу блоками, явно не указываю ни размер блока до сжатия, ни размер блока данных, записываемых в файл. Перепробовал множество комбинаций реализации - МСДНовским способом не прочитать - я же не знаю размер блока, который получится на выходе. Подскажите, пожалуйста, в какую сторону копать - такое чувство, что заблудился в трех соснах!

Решение задачи: «GZipstream - каков принцип многопоточного сжатия/распаковки?»

textual
Листинг программы
public static void Compress(string inFileName)
        {
            int dataPortionSize = Environment.SystemPageSize / threadNumber;
            try
            {
                FileStream inFile = new FileStream(inFileName, FileMode.Open);
                FileStream outFile = new FileStream(inFileName + ".gz", FileMode.Append);
 
                int _dataPortionSize;
                Thread[] tPool;
 
                Console.Write("Compressing...");
 
                while (inFile.Position < inFile.Length)
                {
                    Console.Write(".");
                    tPool = new Thread[threadNumber];
                    for (int portionCount = 0;
                         (portionCount < threadNumber) && (inFile.Position < inFile.Length);
                         portionCount++)
                    {
                        if (inFile.Length - inFile.Position <= dataPortionSize)
                        {
                            _dataPortionSize = (int)(inFile.Length - inFile.Position);
                        }
                        else
                        {
                            _dataPortionSize = dataPortionSize;
                        }
                        dataArray[portionCount] = new byte[_dataPortionSize];
                        inFile.Read(dataArray[portionCount], 0, _dataPortionSize);
 
                        tPool[portionCount] = new Thread(CompressBlock);
                        tPool[portionCount].Start(portionCount);
                    }
 
                    for (int portionCount = 0; (portionCount < threadNumber) && (tPool[portionCount] != null); )
                    {
                        if (tPool[portionCount].ThreadState == ThreadState.Stopped)
                        {
                            BitConverter.GetBytes(compressedDataArray[portionCount].Length+1)
                                        .CopyTo(compressedDataArray[portionCount], 4);
                            outFile.Write(compressedDataArray[portionCount], 0, compressedDataArray[portionCount].Length);
                            portionCount++;
                        }
                    }
 
                }
 
                outFile.Close();
                inFile.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR:" + ex.Message);
            }
        }
 
        public static void CompressBlock(object i)
        {
            using (MemoryStream output = new MemoryStream(dataArray[(int)i].Length))
            {
                using (GZipStream cs = new GZipStream(output, CompressionMode.Compress))
                {
                    cs.Write(dataArray[(int)i], 0, dataArray[(int)i].Length);
                }
                compressedDataArray[(int)i] = output.ToArray();
            }
        }
 
        public static void Decompress(string inFileName)
        {
            try
            {
                FileStream inFile = new FileStream(inFileName, FileMode.Open);
                FileStream outFile = new FileStream(inFileName.Remove(inFileName.Length - 3), FileMode.Append);
                int _dataPortionSize;
                int compressedBlockLength;
                Thread[] tPool;
                Console.Write("Decompressing...");
                byte[] buffer = new byte[8];
 
 
                while (inFile.Position < inFile.Length)
                {
                    Console.Write(".");
                    tPool = new Thread[threadNumber];
                    for (int portionCount = 0;
                         (portionCount < threadNumber) && (inFile.Position < inFile.Length);
                         portionCount++)
                    {
                        inFile.Read(buffer, 0, 8);
                        compressedBlockLength = BitConverter.ToInt32(buffer, 4);
                        compressedDataArray[portionCount] = new byte[compressedBlockLength+1];
                        buffer.CopyTo(compressedDataArray[portionCount], 0);
 
                        inFile.Read(compressedDataArray[portionCount], 8, compressedBlockLength - 8);
                        _dataPortionSize = BitConverter.ToInt32(compressedDataArray[portionCount], compressedBlockLength - 4);
                        dataArray[portionCount] = new byte[_dataPortionSize];
 
                        tPool[portionCount] = new Thread(DecompressBlock);
                        tPool[portionCount].Start(portionCount);
                    }
 
                    for (int portionCount = 0; (portionCount < threadNumber) && (tPool[portionCount] != null); )
                    {
                        if (tPool[portionCount].ThreadState == ThreadState.Stopped)
                        {
                            outFile.Write(dataArray[portionCount], 0, dataArray[portionCount].Length);
                            portionCount++;
                        }
                    }
                }
 
                outFile.Close();
                inFile.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR:" + ex.Message);
            }
        }
 
        public static void DecompressBlock(object i)
        {
            using (MemoryStream input = new MemoryStream(compressedDataArray[(int)i]))
            {
 
                using (GZipStream ds = new GZipStream(input, CompressionMode.Decompress))
                {
                    ds.Read(dataArray[(int)i], 0, dataArray[(int)i].Length);
                }
 
            }
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.133 из 5
Похожие ответы