Пример #1
0
        /// <summary>
        /// Deserializes a compressed data object from the given file stream.
        /// </summary>
        /// <param name="inputStream">input file stream</param>
        /// <returns>object with a compressed byte[] and corresponding index</returns>
        public static IndexedDataObject Deserialize(FileStream inputStream)
        {
            IFormatter        formatter            = new BinaryFormatter();
            IndexedDataObject compressedDataObject = (IndexedDataObject)formatter.Deserialize(inputStream);

            return(compressedDataObject);
        }
Пример #2
0
        /// <summary>
        /// Compresses data inside the input indexedDataObject.
        /// </summary>
        /// <param name="dataObjectForCompression">input data object with byte[] and corresponding index</param>
        /// <returns>data object with compressed byte[] and corresponding index</returns>
        protected override IndexedDataObject ProcessData(IndexedDataObject dataObjectForCompression)
        {
            byte[] processedBlock = Compression.Compress(dataObjectForCompression.DataBlock);
            dataObjectForCompression.DataBlock = processedBlock;
            IndexedDataObject compressedDataObject = dataObjectForCompression;

            return(compressedDataObject);
        }
 /// <summary>
 /// Reads (deserializes) indexed data objects wth compressed byte arrays from an input file and inserts them to the queue.
 /// </summary>
 /// <param name="inputFileStream">input file</param>
 protected override void ReadFromFileAndEnqueue(FileStream inputFileStream)
 {
     while (inputFileStream.Position != inputFileStream.Length)
     {
         IndexedDataObject compressedDataObject = Deserialization.Deserialize(inputFileStream);
         EnqueueObject(compressedDataObject);   // put the data block into the queue
     }
 }
Пример #4
0
        /// <summary>
        /// puts the indexed data object into a queue
        /// </summary>
        /// <param name="data"></param>
        protected void EnqueueObject(IndexedDataObject data)
        {
            lock (lockQueue)
            {
                while (queue.Count >= Settings.maxQueueSize)
                {
                    Monitor.Wait(lockQueue);
                }

                queue.Enqueue(data);

                if (queue.Count == 1)
                {
                    // wake up any blocked dequeue, i.e. the consumer threads
                    Monitor.PulseAll(lockQueue);
                }
            }
        }
        /// <summary>
        /// Reads data blocks (as byte[]) from an input file, assigns a unique number to each block (so that compressed data can later be saved to a file in the correct order)
        /// and inserts a new indexed data object (containing the input data block and the block number) to the queue.
        /// </summary>
        /// <param name="inputFileStream">input file</param>
        protected override void ReadFromFileAndEnqueue(FileStream inputFileStream)
        {
            byte[] block = new byte[Settings.blockSize];
            int    bytesRead;
            uint   i = 1;

            while ((bytesRead = (inputFileStream).Read(block, 0, Settings.blockSize)) > 0)     // read "blockSize" of bytes to a "block" (byte[])
            {
                if (bytesRead < block.Length)
                {
                    byte[] block2 = new byte[bytesRead];
                    Array.Copy(block, block2, bytesRead);
                    block = block2;
                }

                IndexedDataObject indexedDataObject = new IndexedDataObject(block, i);

                EnqueueObject(indexedDataObject);   // put the data block into the queue

                block = new byte[Settings.blockSize];

                i++;
            }
        }
Пример #6
0
 /// <summary>
 /// Writes compressed data from the given data object to a file (using object serialization).
 /// </summary>
 /// <param name="outputDataObject">data object to be written (serialized) into the output file</param>
 /// <param name="outputFileStream">output file</param>
 protected override void WriteToFile(IndexedDataObject outputDataObject, FileStream outputFileStream)
 {
     Serialization.Serialize(outputDataObject, outputFileStream);
 }
 /// <summary>
 /// Writes decompressed data from the given indexed data object to the output file (in correct order based on the data objects's index number) as byte[].
 /// </summary>
 /// <param name="outputDataObject">data object with byte[] to be written into the output file</param>
 /// <param name="outputFileStream">output file</param>
 protected override void WriteToFile(IndexedDataObject outputDataObject, FileStream outputFileStream)
 {
     outputFileStream.Write(outputDataObject.DataBlock, 0, outputDataObject.DataBlock.Length);
 }
Пример #8
0
        /// <summary>
        /// Serializes a compressed data object to the given file stream.
        /// </summary>
        /// <param name="compressedDataObject">object with a compressed byte[] and corresponding index</param>
        /// <param name="outputStream">output file stream</param>
        public static void Serialize(IndexedDataObject compressedDataObject, FileStream outputStream)
        {
            IFormatter formatter = new BinaryFormatter();

            formatter.Serialize(outputStream, compressedDataObject);
        }
Пример #9
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."));
            }
        }
Пример #10
0
 /// <summary>
 /// Writes the processed data into the output file.
 /// </summary>
 /// <param name="outputDataObject">data object to be written in the output file</param>
 /// <param name="outputFileStream">output file</param>
 protected abstract void WriteToFile(IndexedDataObject outputDataObject, FileStream outputFileStream);
Пример #11
0
 /// <summary>
 /// Retrieves an indexed data object from the queue nad processes it (compresses or decompresses the data).
 /// </summary>
 /// <param name="indexedDataObject"></param>
 /// <returns>data object with compressed or decompressed byte[] and corresponding index</returns>
 protected abstract IndexedDataObject ProcessData(IndexedDataObject indexedDataObject);