Написал несколько методов, один читает файл по частям, далее все складываю в очередь необработанных блоков, следующий метод сжимает каждый блок, далее в цикле я кладу сжатые блоки в новую очередь готовых блоков. Потом соответственно, беру блоки из готовой очереди и просто пишу их в файл.
Но заметил такую штуку, до того как были готовы методы сжатия и до того как я добавлял сжатые блоки в готовую очередь, все было нормально. мой файл распадался на 32 части и эти части лежали в очереди для необработанных блоков,но после подключения метода ,который сжимает данные и эти данные я далее добавляю в очередь с готовым материалом, у меня почему то в очереди с необработанными блоками их количество упало в два раза, было 32 блока, стало 16, и по логике я понимаю, что в очереди с готовыми блоками у меня должно быть такое же количество блоков, они по размеру будут другие, а количество не измениться. Подскажите что не так в логике или исполнении.
Вот код.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO.Compression;
namespace ConsoleApplication57
{
class Program
{
static void Main(string[] args)
{
string path = @"d:\Black Widow.m4a";
string path_compres = @"d:\Compress.gz";
// создаем очередь c блоками ланных
Queue<KeyValuePair<int, byte[]>> queue_block = new Queue<KeyValuePair<int, byte[]>>();
// создаем очередь с готовыми обработанными блоками
Queue<KeyValuePair<int, byte[]>> readyQueue = new Queue<KeyValuePair<int, byte[]>>();
// открываем поток
using (var fs = new FileStream(path, FileMode.Open))
// добавляем в очередь блоки
foreach (KeyValuePair<int, byte[]> block in Read_Blockk(fs))
{
queue_block.Enqueue(block);
}
// сжимаем и добавляем в готовую очередь
while (queue_block.Peek().Key<queue_block.Count)
{
int count = 0;
foreach (KeyValuePair<int, byte[]> ready_block in COmpress(count, queue_block.Dequeue().Value))
{
readyQueue.Enqueue(ready_block);
count++;
}
}
// пишем в файл блоки
while (readyQueue.Count!=0)
{
Write_Final_File(path_compres,readyQueue.Dequeue().Value);
}
Console.ReadKey();
}
public static IEnumerable<KeyValuePair<int,byte[]>> Read_Blockk(Stream stream)
{
const int size_block=1024 * 1024; // определяем размер буфера=1мб
int index = 0; // номер блока
while (stream.Position<stream.Length)
{
// выделяем память под массив буффера.
byte[] buffer=new byte[System.Math.Min(size_block,stream.Length-stream.Position)];
stream.Read(buffer, 0, buffer.Length);
yield return new KeyValuePair<int, byte[]>(index++,buffer);
}
}
public static IEnumerable<KeyValuePair<int, byte[]>> COmpress(int index,byte[] block)
{
using (var ms = new MemoryStream())
using (var gzStream=new GZipStream(ms,CompressionMode.Compress))
{
int ind = index;
gzStream.Write(block,0,block.Length);
gzStream.Close();
yield return new KeyValuePair<int, byte[]>(ind++,ms.ToArray());
}
}
public static void Write_Final_File(string path, byte[] ReadyBlock)
{
using (var fsWrite = new FileStream(path, FileMode.Append, FileAccess.Write))
fsWrite.Write(ReadyBlock,0,ReadyBlock.Length);
}
}
}