How to check corrupted zip files?

Oct 22, 2008 at 2:07 PM
Edited Oct 22, 2008 at 3:06 PM
I'm trying to check zip file using this code, but get an exception (OutOfMemoryException) when I try to extract big files.
There are other ways to check corrupted file?
Thanks
sorry for my english :p
 

Private

 

Function checkCRCZip(ByVal filezip As String, ByVal dir As String) As String
Dim 

 

ZipFileToCheck As String = filezip
Dim mStream As MemoryStream
Dim output As String = ""
Dim zip As ZipFile = ZipFile.Read(ZipFileToCheck)
Dim zEntry As ZipEntry

    Try
        
For Each zEntry In Zip
            mStream = New MemoryStream()
            zEntry.Extract(mStream) 
            output = String.Format("0x{1:X8}", zEntry.FileName, zEntry.Crc32)
        Next  
    
Catch ex As BadReadException
        MessageBox.Show(ex.Message.ToString)
        output =
""
    Catch ex As BadCrcException
        MessageBox.Show(ex.Message.ToString)
        output =
""
    End Try

checkCRCZip = output
End Function

 

 

 

 

Coordinator
Oct 22, 2008 at 3:48 PM
The most reliable way to "check" a zip file is to actually extract all the entries within it. 
There can be a corruption at any point in the file, and the only way to find out is to extract each entry.
This validates the checksums and data sizes and so on.

In your case, you are extracting to a memory stream which keeps all file (entry) contents in memory. For large files this is a problem, and you get the out-of-memory exception.

I think what you may want is a stream with no storage at all, a "bit bucket". 

Try System.IO.Stream.Null
Oct 23, 2008 at 7:49 AM
Edited Oct 23, 2008 at 10:13 AM
I can't find Stream in VB2005.
There are only StreamReader and StreamWriter.

EDIT: Sorry, I find it :p

Coordinator
Oct 24, 2008 at 1:28 AM

Glad you found it.

Here's some code for anyone else who wants to try this: 

            If File.Exists(ZipToCheck) Then

                Console.WriteLine("Checking the zip file: {0}", ZipToCheck)

                Dim bitBucket As System.IO.Stream
                bitBucket = System.IO.Stream.Null

                Using zip As ZipFile = ZipFile.Read(ZipToCheck)
                    Dim zEntry As ZipEntry

                    Try
                          For Each zEntry In Zip
                              If NOT zEntry.IsDirectory Then 
                                  zEntry.Extract(bitBucket) 
                                  Console.WriteLine("  {0,-48}   0x{1:X8}", zEntry.FileName, zEntry.Crc32)
                              End If
                          Next  
                    Catch ex As BadReadException
                          Console.WriteLine(ex.Message.ToString)
                    Catch ex As BadCrcException
                          Console.WriteLine(ex.Message.ToString)
                    End Try
                End Using

            Else
                Console.WriteLine("The zip file '{0}' does not exist.", ZipToCheck)
            End If

If you think it is valuable, I could add a method to the ZipFile class to do this. It could be a matter of adding an overload to the existing static ZipFile.IsZipFile() method.