コード例 #1
0
ファイル: Reader.cs プロジェクト: viyy/GZipTest
        /// <summary>
        ///     Читаем блоки файла для архивации
        /// </summary>
        /// <param name="filepath">Входной файл</param>
        /// <param name="bufferSize">Размер блока</param>
        private void ReadForCompress(string filepath, int bufferSize)
        {
            var fileLength     = new FileInfo(filepath).Length;
            var availableBytes = fileLength;

            while (availableBytes > 0)
            {
                while (_maxChunks != 0 && InputChunkHolder.Count >= _maxChunks)
                {
                    lock (InputChunkHolder.DequeueWaitObject)
                    {
                        Monitor.Wait(InputChunkHolder.DequeueWaitObject);
                    }
                }

                while (GCUtils.FreeMemoryMb() < Constants.MinMemoryFreeMb)
                {
                    //Console.WriteLine(GCUtils.FreeMemoryMb()+"Mb left!");
                    GCUtils.ForceGc();
                }
                //сколько читать
                var readCount = availableBytes < bufferSize
                    ? (int)availableBytes
                    : bufferSize;
                using (var reader =
                           new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)))
                {
                    reader.BaseStream.Seek(fileLength - availableBytes, SeekOrigin.Begin);
                    var bytes = reader.ReadBytes(readCount);
                    InputChunkHolder.Enqueu(new Chunk(ChunksReaded, bytes));
                }
                //двигаем счётчики
                availableBytes -= readCount;
                ChunksReaded++;
                //Console.WriteLine($"Readed #{ChunksReaded-1}");
            }
            FileReaded = true;
            //Console.WriteLine($"Total chunks {ChunksReaded-1}");
        }
コード例 #2
0
ファイル: Reader.cs プロジェクト: viyy/GZipTest
        /// <summary>
        ///     Читаем блоки архива
        /// </summary>
        /// <param name="filepath">Входной файл</param>
        private void ReadForDecompress(string filepath)
        {
            using (var reader = new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read)))
            {
                var gzipHeader = Constants.GZipHeader;

                var fileLength     = new FileInfo(filepath).Length;
                var availableBytes = fileLength;
                while (availableBytes > 0)
                {
                    while (GCUtils.FreeMemoryMb() < Constants.MinMemoryFreeMb)
                    {
                        //Console.WriteLine(GCUtils.FreeMemoryMb() + "Mb left!");
                        GCUtils.ForceGc();
                    }
                    var gzipBlock = new List <byte>();
                    //Console.WriteLine($"Reading #{ChunksReaded}");
                    // GZip Заголовок
                    if (ChunksReaded == 0) // Получаем первый заголовок в файле. В остальных блоках - такой же
                    {
                        gzipHeader      = reader.ReadBytes(gzipHeader.Length);
                        availableBytes -= gzipHeader.Length;
                    }
                    gzipBlock.AddRange(gzipHeader); //добавляем хидер в блок

                    // Данные блока архива
                    var gzipHeaderMatchsCount = 0;
                    while (availableBytes > 0)
                    {
                        while (_maxChunks != 0 && InputChunkHolder.Count >= _maxChunks)
                        {
                            lock (InputChunkHolder.DequeueWaitObject)
                            {
                                //Console.WriteLine("Waiting for Dq");
                                Monitor.Wait(InputChunkHolder.DequeueWaitObject);
                            }
                        }

                        var curByte = reader.ReadByte();
                        gzipBlock.Add(curByte);
                        availableBytes--;

                        // Проверяем заголовок следующего блока
                        if (curByte == gzipHeader[gzipHeaderMatchsCount])
                        {
                            gzipHeaderMatchsCount++;
                            if (gzipHeaderMatchsCount != gzipHeader.Length)
                            {
                                continue;
                            }

                            gzipBlock.RemoveRange(gzipBlock.Count - gzipHeader.Length,
                                                  gzipHeader.Length); // Убираем заголовок следующего блока из текущего
                            break;
                        }

                        gzipHeaderMatchsCount = 0;
                    }
                    //отправляем блок на обработку
                    InputChunkHolder.Enqueu(new Chunk(ChunksReaded, gzipBlock.ToArray()));
                    //номер блока ++
                    ChunksReaded++;
                    //Console.WriteLine($"Readed #{ChunksReaded - 1}");
                }
            }
            FileReaded = true;
            //Console.WriteLine($"Total chunks {ChunksReaded - 1}");
        }