CompressedSize in local header does not match that of central directory header in new zip file

I have a strange problem when creating a new Zip archive using SharpZipLib. I can create the Zip file successfully and it can be read fine by various Zip utilities, but when extracting the file contained within, I get an error resembling the following:

  • 'The compressed size stored in the local header for this file is not the same as the compressed size stored in the central directory header.'

Using a Hex editor, I can see that indeed the Central directory header has a compressed size of 64 bytes (correct) for my file, but the local header is FFFF which is incorrect. I have debugged my code and have found that the CompressedSize of the ZipEntry object gets set when you call ZipOutputStream.Finish() but the data in the stream does not get updated with this value - presumably because it was written to the stream before the compressedsize was available. Short of manually searching the stream and updating the value with the value ripped from the Central directory header, which is a bit hacky, I'm out of ideas. If anyone can spot anything obvious I'm doing wrong, it would be very much appreciated.

My code is as follows:

        // get the data and store in unzipped byte array
        Byte[ unzippedData = encoding.GetBytes(data);
        // create CRC for unzipped data
        Crc32 crc = new Crc32();
        crc.Reset();
        crc.Update(unzippedData);

        // create memory stream to hold zipped data
        MemoryStream zippedStream = new MemoryStream();
        ZipOutputStream zipOut = new ZipOutputStream(zippedStream);
       
        ZipEntry zipEntry = new ZipEntry(ConfigurationManager.AppSettings["CSVName"]);
        zipEntry.CompressionMethod = CompressionMethod.Deflated;     
        zipEntry.Size = unzippedData.Length;
        zipEntry.Crc = crc.Value;
        zipEntry.ZipFileIndex = 1;
        zipEntry.DateTime = DateTime.Now;
       
        // write header for our csv file
        zipOut.PutNextEntry(zipEntry);   
        // write the file data
        zipOut.Write(unzippedData, 0, unzippedData.Length);

        // ** ONLY AFTER THIS POINT DOES THE COMPRESSEDSIZE GET SET IN ZIPENTRY
        zipOut.Finish();
        zipOut.Flush();
        // insert the NHS string at beginning of data, before header
        IEnumerable<Byte> zippedData = zippedStream.ToArray();
        IEnumerable<Byte> nhsString = encoding.GetBytes(_NHSZipString);
        zippedData = nhsString.Concat(zippedData);

        // clean up
        zipOut.Close();

        // return as array of bytes
        return zippedData.ToArray();

 Many thanks

 Dan

 

 

 

 

 

 

 

Answer

 

 

Just a quick follow up. This problem seems to be resolved if I don't set the CRC for the ZipEntry - the local header has the expected value and the file extracts successfully in multiple Zip applications. This ring any bells with anyone?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章