public override void Handle(ref TaskPool readPool, ref TaskPool writePool) { int blockNumber = -1; byte[] blockValue = null; while (true) { try { if (!readPool.TryGet(out blockNumber, out blockValue)) { return; } if (blockValue == null) { break; } byte[] decompressedBlock = ApplyGZip(blockValue); if (!writePool.TrySet(blockNumber, decompressedBlock)) { return; } } catch (Exception e) { _delete = true; Terminate(); Console.WriteLine(e.Message); return; } } }
public override void WriteFile(string destination, ref TaskPool writePool) { try { FileInfo fi = new FileInfo(destination); DriveInfo drive = new DriveInfo(fi.Directory.Root.FullName); if (drive.DriveFormat == "FAT32" && _originLength > MAX_FILE_SIZE) { throw new IOException("ERROR: недостаточно места на диске записи распакованного файла (ограничение FAT32)"); } } catch (Exception e) { Terminate(); Console.WriteLine(e.Message); return; } int counter = 0; int blockNumber = -1; byte[] blockValue = null; Dictionary <int, byte[]> buffer = new Dictionary <int, byte[]>(); try { using var bw = new BinaryWriter(new FileStream(destination, FileMode.Create, FileAccess.Write, FileShare.None)); while (true) { if (!writePool.TryGet(out blockNumber, out blockValue)) { return; } if (blockValue == null) { break; } buffer[blockNumber] = blockValue; while (buffer.ContainsKey(counter)) { bw.Write(buffer[counter]); buffer.Remove(counter); counter++; ShowProgress((double)counter / _blockCount); if (counter == _blockCount) { Terminate(); return; } } } } catch (Exception e) { _delete = true; Terminate(); Console.WriteLine(e.Message); } if (_delete) { try { File.Delete(destination); } catch (Exception e) { Console.WriteLine(e.Message); return; } } }
public override void WriteFile(string destination, ref TaskPool writePool) { int counter = 0; int blockNumber = -1; byte[] blockValue = null; try { using var binWriter = new BinaryWriter(new FileStream(destination, FileMode.Create, FileAccess.Write, FileShare.None)); binWriter.Write(BitConverter.GetBytes(_sourceFileSize)); binWriter.Write(BitConverter.GetBytes(_blockCount)); while (true) { if (!writePool.TryGet(out blockNumber, out blockValue)) { return; } if (blockValue == null) { break; } try { binWriter.Write(BitConverter.GetBytes(blockNumber)); binWriter.Write(blockValue.Length); binWriter.Write(blockValue); } catch (IOException e) { Terminate(); logger.Error("Writing is terminated ({0})", e.Message); binWriter.Close(); File.Delete(destination); return; } counter++; ShowProgress((double)counter / _blockCount); if (counter == _blockCount) { Terminate(); } } } catch (Exception e) { _delete = true; Terminate(); logger.Warn(e.Message); } if (_delete) { try { File.Delete(destination); } catch (Exception e) { logger.Warn(e.Message); return; } } }
static int Main(string[] args) { if (!ArgumentsValidator.Validate(args, out ArchiverSettings settings)) { return(1); } try { var gzip = new GZip(BUFFER_SIZE); ArchivationProcess archivation = ProcessFactory.GetProcess(settings.Mode, gzip); var progressReport = new ProgressReport(settings.Mode); int coreCount = Environment.ProcessorCount * 2; var readPool = new TaskPool(coreCount); var writePool = new TaskPool(coreCount); Stopwatch sw = new Stopwatch(); sw.Start(); archivation.ShowProgress += progressReport.ShowProgress; archivation.Terminate += readPool.Terminate; archivation.Terminate += writePool.Terminate; Thread readerThread = new Thread(delegate() { archivation.ReadFile(settings.SourceFileName, ref readPool, BUFFER_SIZE); }); Thread writerThread = new Thread(delegate() { archivation.WriteFile(settings.DestinationFileName, ref writePool); }); var handlers = new Thread[coreCount]; for (int i = 0; i < coreCount; i++) { handlers[i] = new Thread(delegate() { archivation.Handle(ref readPool, ref writePool); }); } readerThread.Start(); foreach (Thread handler in handlers) { handler.Start(); } writerThread.Start(); writerThread.Join(); foreach (Thread handler in handlers) { handler.Join(); } readerThread.Join(); sw.Stop(); progressReport.Done(sw.Elapsed); archivation.Terminate -= writePool.Terminate; archivation.Terminate -= readPool.Terminate; archivation.ShowProgress -= progressReport.ShowProgress; } catch (Exception ex) { logger.Fatal(ex.Message); return(1); } finally { logger.Info("Done"); } return(0); }
public abstract void WriteFile(string destination, ref TaskPool writerTaskPool);
public abstract void Handle(ref TaskPool readerTaskPool, ref TaskPool writerTaskPool);
public abstract void ReadFile(string source, ref TaskPool readerTaskPool, int bufferSize);