/// <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}"); }
/// <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}"); }