private void PartDecompressor(object i) { long num = (long)i; byte[] data = null; //Обработка очереди mtx.WaitOne(); if (file_parts_queue.Count != 0) { file_parts_queue.TryDequeue(out data); } mtx.ReleaseMutex(); //Если данные не был считаны if (data == null) { //Записываем индекс с нулевой датой, чтобы сохранить последовательность PartDataContainer pdc = new PartDataContainer(num, null); unzip_parts_list.AddLast(pdc); return; } //Если удалось получить данные из очереди int size = 0; byte[] buf = new byte[bufferSize]; try { using (MemoryStream tmp_stream = new MemoryStream()) { using (GZipStream zip_stream = new GZipStream(new MemoryStream(data), CompressionMode.Decompress)) { //Получаем число распакованных байтов size = zip_stream.Read(buf, 0, bufferSize); //Пишем в поток tmp_stream.Write(buf, 0, size); } //Записываем индекс части и соответствующие данные PartDataContainer pdc = new PartDataContainer(num, tmp_stream.ToArray()); unzip_parts_list.AddLast(pdc); } } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ResetColor(); } }
private void WriterThread() { using (FileStream out_stream = new FileStream(output_file_path, FileMode.Create)) { PartDataContainer dc; int cnt = 1; while (zip_parts_list.Count == 0) { Thread.Sleep(50); } var node = zip_parts_list.First; //Основной цикл записи в файл(архив) while (!reading_ended || zip_parts_list.Count != 0 || compression_thread.ThreadState != ThreadState.Stopped) { if (zip_parts_list.Count != 0) { //Если лист был очищен, а после поступили новые сжатые данные if (node == null) { node = zip_parts_list.First; } dc = new PartDataContainer(node.Value.Index, node.Value.Data); //Находим нужный индекс по порядку if (dc.Index == cnt) { //Если данный индекс имеет данные if (dc.Data != null) { //Записываем в файл out_stream.Write(dc.Data, 0, dc.Data.Length); } //Меняем индекс для поиска следующей части cnt++; //Удаляем элемент из листа zip_parts_list.Remove(node); //Сдвигаем указатель node = zip_parts_list.First; } else { node = node.Next; } } //Если чтение еще идет, но сжатых данных пока нет else { //Ждем Thread.Sleep(50); } } } }
private void PartCompressor(object i) { long num = (long)i; byte[] data = null; //Обработка очереди mtx.WaitOne(); if (file_parts_queue.Count != 0) { file_parts_queue.TryDequeue(out data); } mtx.ReleaseMutex(); //Если данные не был считаны if (data == null) { //Записываем индекс с нулевой датой, чтобы сохранить последовательность PartDataContainer pdc = new PartDataContainer(num, null); zip_parts_list.AddLast(pdc); return; } //Если удалось получить данные из очереди try { using (MemoryStream mem_stream = new MemoryStream(data.Length)) { using (GZipStream zip_stream = new GZipStream(mem_stream, CompressionMode.Compress)) { //Сжимаем zip_stream.Write(data, 0, data.Length); } //Получаем размер сжатого блока int l = mem_stream.ToArray().Length; //Конвертируем в байты byte[] part_size = BitConverter.GetBytes(l); //Подготавливаем массив для записи размеров блока и его содержимого byte[] data_to_write = new byte[l + 4]; //Пишем длину part_size.CopyTo(data_to_write, 0); mem_stream.ToArray().CopyTo(data_to_write, part_size.Length); //Записываем индекс части и соответствующие данные PartDataContainer pdc = new PartDataContainer(num, data_to_write); zip_parts_list.AddLast(pdc); } } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); Console.ResetColor(); } }