ZIP file created with SharpZipLib cannot be opened on Mac OS X

前端 未结 10 1311
有刺的猬
有刺的猬 2021-02-04 08:31

Argh, today is the day of stupid problems and me being an idiot.

I have an application which creates a zip file containing some JPEGs from a certain directory. I use th

相关标签:
10条回答
  • 2021-02-04 09:12

    I had a similar problem but on Windows 7. I updated to the as of this writing latest version of ICSharpZipLib 0.86.0.518. From then on I could no longer decompress any ZIP archives created with the code that was working so far.

    There error messages were different depending on the tool I tried to extract with:

    • Unknown compression method.
    • Compressed size in local header does not match that of central directory header in new zip file.

    What did the trick was to remove the CRC calculation as mentioned here: http://community.sharpdevelop.net/forums/t/8630.aspx

    So I removed the line that is:

    entry.Crc = crc.Value
    

    And from then on I could again unzip the ZIP archives with any third party tool. I hope this helps someone.

    0 讨论(0)
  • 2021-02-04 09:14

    I encountered weird behavior when archive is empty (no entries inside it) it can not be opened on MAC - generates cpgz only. The idea was to put a dummy .txt file in it in case when no files for archiving.

    0 讨论(0)
  • 2021-02-04 09:17

    There are two things:

    • Ensure your underlying output stream is seekable, or SharpZipLib won't be able to back up and fill in any ZipEntry fields that you omitted (size, crc, compressed size, ...). As a result, SharpZipLib will force "bit 3" to be enabled. The background has been explained pretty well in previous answers.

    • Fill in ZipEntry.Size, or explicitly set stream.UseZip64 = UseZip64.Off. The default is to conservatively assume the stream could be very large. Unzipping then requires "pk 4.5" support.

    0 讨论(0)
  • 2021-02-04 09:20

    got the exact same problem today. I tried implementing the CRC stuff as proposed but it didn't help.

    I finaly found the solution on this page: http://community.sharpdevelop.net/forums/p/7957/23476.aspx#23476

    As a result, I just had to add this line in my code:

    oZIPStream.UseZip64 = UseZip64.Off;

    And the file opens up as it should on MacOS X :-)

    Cheers fred

    0 讨论(0)
  • 2021-02-04 09:21

    So, I searched for a few more examples on how to use SharpZipLib and I finally got it to work on Windows and os x. Basically I added the "Crc32" of the file to the zip archive. No idea what this is though.

    Here is the code that worked for me:

            using (var outStream = new FileStream("Out3.zip", FileMode.Create))
            {
                using (var zipStream = new ZipOutputStream(outStream))
                {
                    Crc32 crc = new Crc32();
    
                    foreach (string pathname in pathnames)
                    {
                        byte[] buffer = File.ReadAllBytes(pathname);
    
                        ZipEntry entry = new ZipEntry(Path.GetFileName(pathname));
                        entry.DateTime = now;
                        entry.Size = buffer.Length;
    
                        crc.Reset();
                        crc.Update(buffer);
    
                        entry.Crc = crc.Value;
    
                        zipStream.PutNextEntry(entry);
                        zipStream.Write(buffer, 0, buffer.Length);
                    }
    
                    zipStream.Finish();
    
                    // I dont think this is required at all
                    zipStream.Flush();
                    zipStream.Close();
    
                }
            }
    

    Explanation from cheeso:

    CRC is Cyclic Redundancy Check - it's a checksum on the entry data. Normally the header for each entry in a zip file contains a bunch of metadata, including some things that cannot be known until all the entry data has been streamed - CRC, Uncompressed size, and compressed size. When generating a zipfile through a streamed output, the zip spec allows setting a bit (bit 3) to specify that these three data fields will immediately follow the entry data.

    If you use ZipOutputStream, normally as you write the entry data, it is compressed and a CRC is calculated, and the 3 data fields are written immediately after the file data.

    What you've done is streamed the data twice - the first time implicitly as you calculate the CRC on the file before writing it. If my theory is correct, the what is happening is this: When you provide the CRC to the zipStream before writing the file data, this allows the CRC to appear in its normal place in the entry header, which keeps OSX happy. I'm not sure what happens to the other two quantities (compressed and uncompressed size).


    0 讨论(0)
  • 2021-02-04 09:21

    What's going on with the .cpgz file is that Archive Utility is being launched by a file with a .zip extension. Archive Utility examines the file and thinks it isn't compressed, so it's compressing it. For some bizarre reason, .cpgz (CPIO archiving + gzip compression) is the default. You can set a different default in Archive Utility's Preferences.

    If you do indeed discover this is a problem with OS X's zip decoder, please file a bug. You can also try using the ditto command-line tool to unpack it; you may get a better error message. Of course, OS X also ships unzip, the Info-ZIP utility, but I'd expect that to work.

    0 讨论(0)
提交回复
热议问题