예제 #1
0
        /// <summary>
        /// Reads data from a file and puts it into a queue for a consumer.
        /// </summary>
        public void ProduceData()
        {
            try
            {
                FileInfo inputFile = new FileInfo(Program.GetInputFile());
                using (FileStream inputFileStream = inputFile.OpenRead())
                {
                    ReadFromFileAndEnqueue(inputFileStream);

                    EnqueueObject(null);       // null object is attached to the end of the queue where there are no more bytes to read from the input file => signal the consumer to exit
                }
            }
            catch (DirectoryNotFoundException)
            {
                ErrorsChecker.SetError(new DirectoryNotFoundException("Error message: The input directory you're looking for doesn't exist."));
            }
            catch (DriveNotFoundException)
            {
                ErrorsChecker.SetError(new DriveNotFoundException("Error message: The input drive you're looking for doesn't exist."));
            }
            catch (FileNotFoundException)
            {
                ErrorsChecker.SetError(new FileNotFoundException("Error message: The input file you're looking for doesn't exist."));
            }
            catch (FileLoadException)
            {
                ErrorsChecker.SetError(new FileLoadException("Error message: The input file you're looking has been found but it can't be loaded."));
            }
            catch (PathTooLongException)
            {
                ErrorsChecker.SetError(new PathTooLongException("Error message: The input path is longer or fully qualified file name is longer than the system-defined maximum length."));
            }
            catch (UnauthorizedAccessException)
            {
                ErrorsChecker.SetError(new UnauthorizedAccessException("Error message: Access to the input directory or file was denied."));
            }
            catch (OutOfMemoryException)
            {
                ErrorsChecker.SetError(new OutOfMemoryException("Error message: There is not enough memory to continue the execution of the program."));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                ErrorsChecker.SetError(new Exception("Error message: An error occured during the execution of the program."));
            }
        }
예제 #2
0
        public static int Main(string[] args)
        {
            // check the command line arguments passed to the application and set appropriate action type (compress/decompress) if everything is ok
            ErrorsChecker.CheckInputParameters(args);


            if ("compress".Equals(args[0].ToLower()))
            {
                SetActionType(ActionType.Compress);
            }
            else
            {
                SetActionType(ActionType.Decompress);
            }

            inputFile  = args[1];
            outputFile = args[2];

            // Console.WriteLine("Version using all CPU cores, code refactored, abstract classes utilized");
            Console.WriteLine($"input file: {inputFile}");
            Console.WriteLine($"output file: {outputFile}");

            Stopwatch watch = new Stopwatch();

            watch.Start();

            ProducerConsumer producerConsumer = new ProducerConsumer();

            producerConsumer.RunProducerConsumer(actionType);

            watch.Stop();
            if (actionType == ActionType.Compress)
            {
                Console.WriteLine($"Time needed for compression: {watch.Elapsed} s.");
            }
            else
            {
                Console.WriteLine($"Time needed for decompression: {watch.Elapsed} s.");
            }

            Console.WriteLine("Application finished successfully.");
            return(0);
        }
예제 #3
0
        /// <summary>
        /// Takes data objects from a queue, processes them (compression/decompression) and writes them to the output file.
        /// </summary>
        /// <param name="outputFileStreamObject">output file stream</param>
        public void ConsumeData(object outputFileStreamObject)  //takes data from a queue
        {
            try
            {
                FileStream outputFileStream = (FileStream)outputFileStreamObject;

                while (true)        // keeps the consumer thread running
                {
                    IndexedDataObject dataElementFromQueue = null;

                    lock (lockQueue)
                    {
                        if (queue.Count > 0)        // queue not empty
                        {
                            dataElementFromQueue = queue.Dequeue();

                            Monitor.PulseAll(lockQueue);               // data removed from a queue => wake up the producer to put more data into the queue

                            if (dataElementFromQueue == null)          // null object in queue means end of file reached, nothing more to read
                            {
                                ProducerConsumer.lastBlockRead = true; // last block in the queue (there are no more bytes to read from the input file)
                                return;                                // Producer ended, all objects from the queue have been already processed => this thread ends
                            }
                        }
                        else
                        {
                            if (ProducerConsumer.lastBlockRead)
                            {
                                return;         // Producer ended, all objects from the queue have been already processed (or are processed by other threads) => this thread ends
                            }
                            Monitor.Wait(lockQueue);
                        }
                    }

                    // data object was read from the queue => we can release the lock and enable access to the queue again to the producer or other consumer threads

                    if (dataElementFromQueue != null)
                    {
                        IndexedDataObject processedData = ProcessData(dataElementFromQueue);

                        lock (lockOutputFile)
                        {
                            // thread waits for previous data blocks to be written to the file before it can write its own data block to the file
                            while ((processedData.Index - 1) != ProducerConsumer.GetProcessedBlocksCount())
                            {
                                Monitor.Wait(lockOutputFile);
                            }

                            WriteToFile(processedData, outputFileStream);
                            ProducerConsumer.IncrementProcessedBlocksCount();
                            Monitor.PulseAll(lockOutputFile);
                        }
                    }
                }
            }
            catch (DirectoryNotFoundException)
            {
                ErrorsChecker.SetError(new DirectoryNotFoundException("Error message: The output directory you're looking for doesn't exist."));
            }
            catch (DriveNotFoundException)
            {
                ErrorsChecker.SetError(new DriveNotFoundException("Error message: The output drive you're looking for doesn't exist."));
            }
            catch (PathTooLongException)
            {
                ErrorsChecker.SetError(new PathTooLongException("Error message: The output path is longer or fully qualified file name is longer than the system-defined maximum length."));
            }
            catch (UnauthorizedAccessException)
            {
                ErrorsChecker.SetError(new UnauthorizedAccessException("Error message: Access to the output directory was denied."));
            }
            catch (OutOfMemoryException)
            {
                ErrorsChecker.SetError(new OutOfMemoryException("Error message: There is not enough memory to continue the execution of the program."));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                ErrorsChecker.SetError(new Exception("Error message: An error occured during the execution of the program."));
            }
        }