您的位置:首页 > 其它

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

2010-03-18 18:39 525 查看
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?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐