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);
        }
Beispiel #5
0
 public abstract void WriteFile(string destination, ref TaskPool writerTaskPool);
Beispiel #6
0
 public abstract void Handle(ref TaskPool readerTaskPool, ref TaskPool writerTaskPool);
Beispiel #7
0
 public abstract void ReadFile(string source, ref TaskPool readerTaskPool, int bufferSize);