使用ICSharpZipLib进行文件压缩的例子
private void ZipFiles(string filesDir, string zipFile)
{
string[] filenames = Directory.GetFiles(filesDir);
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(zipFile));
s.SetLevel(5); // 0 - store only to 9 - means best compression
try
{
foreach (string file in filenames)
{
using(FileStream fs = File.OpenRead(file))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
}
}
catch (Exception expt)
{
}
finally
{
s.Finish();
s.Close();
}
}
特殊说明:
1)使用上述代码会导致其他解压程序诸如winzip、winmount等解压软件无法工作,报错是不支持的压缩算法(神奇的是在windows server 2008上可以解压),其原因为entry.Crc = crc.Value;的设置,不进行该项的设置会解决该问题。
一个老外的解释如下
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).
2)new ZipEntry(file);中file如果带有路径信息,将会导致解压时解压到指定的文件夹