/// <summary>
        /// Ensures that the zip file is valid.
        /// </summary>
        /// <param name="validationHandler">
        /// The class to hold the object for progress reporting
        /// </param>
        /// <returns>
        /// True if the zip is valid, otherwise False.
        /// </returns>
        public static bool Validate(ZipFileValidationHandler validationHandler)
        {
            var buf = new byte[1024 * 256];
            try
            {
                var zip = new ZipFile(validationHandler.Filename);
                ZipFileEntry[] entries = zip.GetAllEntries();

                // First calculate the total compressed length
                long totalCompressedLength = entries.Sum(entry => entry.CompressedSize);
                float averageVerifySpeed = 0;
                long totalBytesRemaining = totalCompressedLength;
                validationHandler.TotalBytes = totalCompressedLength;

                // Then calculate a CRC for every file in the Zip file,
                // comparing it to what is stored in the Zip directory
                foreach (ZipFileEntry entry in entries)
                {
                    if (entry.Crc32 != -1)
                    {
                        DateTime startTime = DateTime.UtcNow;

                        var crc = new Crc32();

                        uint offset = entry.FileOffset;
                        var length = (int)entry.CompressedSize;

                        Stream raf = zip.zipFileStream;
                        raf.Seek(offset, SeekOrigin.Begin);

                        while (length > 0)
                        {
                            int seek = length > buf.Length ? buf.Length : length;
                            raf.Read(buf, 0, seek);
                            crc.Update(buf, 0, seek);
                            length -= seek;

                            DateTime currentTime = DateTime.UtcNow;
                            var timePassed = (float)(currentTime - startTime).TotalMilliseconds;
                            if (timePassed > 0)
                            {
                                float currentSpeedSample = seek / timePassed;
                                if (averageVerifySpeed <= 0)
                                {
                                    averageVerifySpeed = (SmoothingFactor * currentSpeedSample)
                                                         + ((1 - SmoothingFactor) * averageVerifySpeed);
                                }
                                else
                                {
                                    averageVerifySpeed = currentSpeedSample;
                                }

                                totalBytesRemaining -= seek;
                                var timeRemaining = (long)(totalBytesRemaining / averageVerifySpeed);

                                validationHandler.AverageSpeed = averageVerifySpeed;
                                validationHandler.CurrentBytes = totalCompressedLength - totalBytesRemaining;
                                validationHandler.TimeRemaining = timeRemaining;

                                validationHandler.UpdateUi(validationHandler);
                            }

                            startTime = currentTime;
                            if (validationHandler.ShouldCancel)
                            {
                                return true;
                            }
                        }

                        if (crc.Value != entry.Crc32)
                        {
                            Debug.WriteLine("CRC does not match for entry: " + entry.FilenameInZip);
                            Debug.WriteLine("In file: " + entry.ZipFileName);

                            return false;
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
                return false;
            }

            return true;
        }
示例#2
0
        /// <summary>
        /// Ensures that the zip file is valid.
        /// </summary>
        /// <param name="validationHandler">
        /// The class to hold the object for progress reporting
        /// </param>
        /// <returns>
        /// True if the zip is valid, otherwise False.
        /// </returns>
        public static bool Validate(ZipFileValidationHandler validationHandler)
        {
            var buf = new byte[1024 * 256];

            try
            {
                var            zip     = new ZipFile(validationHandler.Filename);
                ZipFileEntry[] entries = zip.GetAllEntries();

                // First calculate the total compressed length
                long  totalCompressedLength = entries.Sum(entry => entry.CompressedSize);
                float averageVerifySpeed    = 0;
                long  totalBytesRemaining   = totalCompressedLength;
                validationHandler.TotalBytes = totalCompressedLength;

                // Then calculate a CRC for every file in the Zip file,
                // comparing it to what is stored in the Zip directory
                foreach (ZipFileEntry entry in entries)
                {
                    if (entry.Crc32 != -1)
                    {
                        DateTime startTime = DateTime.UtcNow;

                        var crc = new Crc32();

                        uint offset = entry.FileOffset;
                        var  length = (int)entry.CompressedSize;

                        Stream raf = zip.zipFileStream;
                        raf.Seek(offset, SeekOrigin.Begin);

                        while (length > 0)
                        {
                            int seek = length > buf.Length ? buf.Length : length;
                            raf.Read(buf, 0, seek);
                            crc.Update(buf, 0, seek);
                            length -= seek;

                            DateTime currentTime = DateTime.UtcNow;
                            var      timePassed  = (float)(currentTime - startTime).TotalMilliseconds;
                            if (timePassed > 0)
                            {
                                float currentSpeedSample = seek / timePassed;
                                if (averageVerifySpeed <= 0)
                                {
                                    averageVerifySpeed = (SmoothingFactor * currentSpeedSample)
                                                         + ((1 - SmoothingFactor) * averageVerifySpeed);
                                }
                                else
                                {
                                    averageVerifySpeed = currentSpeedSample;
                                }

                                totalBytesRemaining -= seek;
                                var timeRemaining = (long)(totalBytesRemaining / averageVerifySpeed);

                                validationHandler.AverageSpeed  = averageVerifySpeed;
                                validationHandler.CurrentBytes  = totalCompressedLength - totalBytesRemaining;
                                validationHandler.TimeRemaining = timeRemaining;

                                validationHandler.UpdateUi(validationHandler);
                            }

                            startTime = currentTime;
                            if (validationHandler.ShouldCancel)
                            {
                                return(true);
                            }
                        }

                        if (crc.Value != entry.Crc32)
                        {
                            Debug.WriteLine("CRC does not match for entry: " + entry.FilenameInZip);
                            Debug.WriteLine("In file: " + entry.ZipFileName);

                            return(false);
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.ToString());
                Console.Write(e.StackTrace);
                return(false);
            }

            return(true);
        }