none
System.io.compression Windows compatibility RRS feed

  • Question

  •  

    Hi,

     

    I am using system.io.compression to allow a user to download files from a web site. The code (see below)  came off the MS example (http://msdn2.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx). 

     

    The problem I am experiencing is that if I open the resultant compressed file with WinRar or WinZip, the file opens OK. However, if I try to open the file using the default Microsoft Compressed Folder utility, I get the message "The Compressed (zipped) Folder is invalid of corrupted".

     

    I would be most grateful if somebody could advise on what I am doing wrong.


    Thanks

    Paul I

     

     

    Imports IO = System.IO
    Imports Zip = System.IO.Compression

     

    Private Function Compress(ByVal FromFile As String, ByVal CompFile As String) as String

    ' compresses the FromFile to CompFile, creating the file.

    ' returns an error message or "" if OK

    Dim sourceFile As IO.FileStream

    Dim destinationFile As IO.FileStream

    Dim buffer() As Byte

    Dim readbytes As Integer

    Dim ZipStrm As Zip.GZipStream = Nothing

     

    Compress = "" ' Optimistic

    sourceFile = IO.File.OpenRead(Server.MapPath(FromFile))

    destinationFile = IO.File.Create(Server.MapPath(CompFile))

    ReDim buffer(sourceFile.Length - 1)

     

    Try

    readbytes = sourceFile.Read(buffer, 0, buffer.Length)

    If readbytes <> buffer.Length Then

    Compress = "Unable to read source file"

    Else

    ZipStrm = New Zip.GZipStream(destinationFile, Zip.CompressionMode.Compress)

    ZipStrm.Write(buffer, 0, buffer.Length)

    End If

     

    Catch ex As Exception

    Compress = ex.Message

     

    Finally

    ZipStrm.Close()

    sourceFile.Close()

    destinationFile.Close()

    End Try

    End Function




    Paul Ireland

     

    Friday, January 4, 2008 8:37 AM

Answers

  • I could be wrong, but the issue could be related to the fact that your compressed information does not contain any header information required by ZIP utility. Basically Microsoft provides class that compresses only actual content, but ZIP file structure also requires compressed file to have header information, which stores file name, original file size, compressed size, compression method etc. That header information is not created by .NET classes and you would need to create it using your own code. Most likely Windows library that provides compression capabilities fails because it cannot find required information. Actual Winzip could try decompressing it in some sort of recovery mode, so it could be smart enough to see that header information is missing and tries just to decompress the content.

     

    Monday, January 7, 2008 11:08 AM
    Moderator

All replies

  • I am assuming your problem is related to you using that class without adding the needed HTTP Module, classes and needed IIS configuration because most classes when you need to use them for web application things change.  The first link is code sample with known issues and the last two links are alternatives.  You also need to adjust your MaxLength property because it default to 4megs but can be adjusted.  Hope this helps.

     

    http://www.west-wind.com/WebLog/posts/102969.aspx


    http://www.codeplex.com/httpcompression


    http://www.microsoft.com/belux/msdn/nl/community/columns/desmet/compression.mspx

    Saturday, January 5, 2008 1:23 AM
  • Thanks for the information it is very interesting and informative. Please could you confirm my understanding of your reply is correct.

     

    Your links appear to relate to creating a Web page that returns a compressed page impression to the browser. If configured to use HTTP 1.1 the browser will then decompress that page and display it.

     

    My requirement is different as I wish to return a compressed file wich the user can choose to store on their PC. This Web application is used to manage an Access database for a small organisation. The compress functionality is to allow the admin user to download a copy of this database for backup purposes. 

     

    The code sample above works if WinZip or WinRar are installed on the client PC, if not Windows shows the resltant file as a compressed folder but will not open it suggesting to me the generated file format is not compatible with Windows.

    Monday, January 7, 2008 10:33 AM
  • I could be wrong, but the issue could be related to the fact that your compressed information does not contain any header information required by ZIP utility. Basically Microsoft provides class that compresses only actual content, but ZIP file structure also requires compressed file to have header information, which stores file name, original file size, compressed size, compression method etc. That header information is not created by .NET classes and you would need to create it using your own code. Most likely Windows library that provides compression capabilities fails because it cannot find required information. Actual Winzip could try decompressing it in some sort of recovery mode, so it could be smart enough to see that header information is missing and tries just to decompress the content.

     

    Monday, January 7, 2008 11:08 AM
    Moderator
  • No using the browser to uncompress the file is just an option and you did not say you are compressing database files because that could be the problem I don't think you should compress a database file and expect Windows file system to uncompress it for you.

     

    Monday, January 7, 2008 2:13 PM
  • As far as I was aware, Windows works with two compression methods.

    • The file system (as in Properties, Advanced, Compress contents.. )
    • Compressed (zipped) Folders (i.e files with the extension .ZIP)

    I do not expect the Windows file system to uncompress the file for me. The code above returns a file with the extension .ZIP to the browser. If the user then saves this file to their PC, Windows shows it as a Compressed (zipped) Folder. Double clicking on this folder to open it produces the error. However, the same file can be opened with WinRar or WinZip.

     

    It sounds like the previous comment about headers may be correct. However, what additional code would I need to make the file compatible with Windows Compressed (zipped) folders?

     

    Thanks

     

    Monday, January 7, 2008 3:57 PM
  • (The file system (as in Properties, Advanced, Compress contents.. )
    Compressed (zipped) Folders (i.e files with the extension .ZIP)

     


    You did not see database included above because as I remember Access database file can grow to 1gig in size, it is not practical for you to use a compression class to compress a database and uncompress it with the file system.  If I had seen a database is what you are trying to compress and uncompress I will not be in this thread because there are reasons database files are created and handled with a lot of care something you don't understand.  Goodluck.

     

    Monday, January 7, 2008 4:10 PM
  • In this particular case the file I need to compress is a very small Access database. I can assure you I fully understand the constraints relating to databases, I have omitted the code that ensures the database is closed and the file locked for unique access for clarity. Additionally I have already performed sizing estimates that suggest the database will grow to a maximum of 4 - 6 Mb. Something I assume would have been well within the capabilities of the compression component.

     

    The issue here is not that the file is a database. I get the same results with ANY file, for example even a text file containing nothing more than "hello there this is a small text file" this fails with the same results as described above.

     

    Must I conclude, therefore, that the Windows System.io.compression component is not compatible with Windows Compressed (zipped) folders?

    Monday, January 7, 2008 4:27 PM
  • You basically need to request specification for ZIP file format from PKWARE and then generate zip files using your own code. It is not really hard (I have done it before), since actual compression part done in .NET classes already. You would need to generate all the supporting part of the file (file size, file name etc). I remember that specification was available for free download at http://www.pkware.com/ but I cannot find direct link to it now.

     

    Tuesday, January 8, 2008 3:03 AM
    Moderator