文件压缩/解压缩开源项目SharpZipLib在C#中的使用
时间:2011-05-19 来源:独孤伤
.net2.0,虽然也有一个解压缩的类,但是好像并不怎么受欢迎。不过我们还可以选择别SharpZipLib。
我从网上找了一些代码,有些做了修改,已经测试可以使用。解压缩操作类:
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
namespace VeryCodes.Common
{
public class ZipHelper
{
///
/// 压缩单个文件
///
///要压缩的文件
///
///压缩后的文件
///
///压缩等级
///
///每次写入大小
public static void ZipFile(string fileToZip, string zipedFile,
int compressionLevel, int blockSize)
{
//如果文件没有找到,则报错
if (!System.IO.File.Exists(fileToZip))
{
throw new System.IO.FileNotFoundException("指定要压缩的文件: " +
fileToZip + " 不存在!");
}
using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile))
{
using (ZipOutputStream ZipStream = new ZipOutputStream(ZipFile))
{
using (System.IO.FileStream StreamToZip =
new System.IO.FileStream(fileToZip, System.IO.FileMode.Open,
System.IO.FileAccess.Read))
{
string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
ZipEntry ZipEntry = new ZipEntry(fileName);
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(compressionLevel);
byte[] buffer = new byte[blockSize];
int sizeRead = 0;
try
{
do
{
sizeRead = StreamToZip.Read(buffer, 0, buffer.Length);
ZipStream.Write(buffer, 0, sizeRead);
}
while (sizeRead > 0);
}
catch (System.Exception ex)
{
throw ex;
}
StreamToZip.Close();
}
ZipStream.Finish();
ZipStream.Close();
}
ZipFile.Close();
}
}
///
/// 压缩单个文件
///
///要进行压缩的文件名
///
///压缩后生成的压缩文件名
public static void ZipFile(string fileToZip, string zipedFile)
{
//如果文件没有找到,则报错
if (!File.Exists(fileToZip))
{
throw new System.IO.FileNotFoundException("指定要压缩的文件: " +
fileToZip + " 不存在!");
}
using (FileStream fs = File.OpenRead(fileToZip))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
using (FileStream ZipFile = File.Create(zipedFile))
{
using (ZipOutputStream ZipStream = new ZipOutputStream(ZipFile))
{
string fileName =
fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
ZipEntry ZipEntry = new ZipEntry(fileName);
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(5);
ZipStream.Write(buffer, 0, buffer.Length);
ZipStream.Finish();
ZipStream.Close();
}
}
}
}
///
/// 压缩多层目录
///
///压缩目录
///
///压缩文件流
///
public static void ZipFileDirectory(string strDirectory, string zipedFile)
{
using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile))
{
using (ZipOutputStream s = new ZipOutputStream(ZipFile))
{
ZipSetp(strDirectory, s, "");
}
}
}
///
/// 递归遍历目录
///
///
private static void ZipSetp(string strDirectory,
ZipOutputStream s, string parentPath)
{
if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
{
strDirectory += Path.DirectorySeparatorChar;
}
Crc32 crc = new Crc32();
string[] filenames = Directory.GetFileSystemEntries(strDirectory);
// 遍历所有的文件和目录
foreach (string file in filenames)
{
// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
if (Directory.Exists(file))
{
parentPath += file.Substring(file.LastIndexOf("\\") + 1);
parentPath += "\\";
ZipSetp(file, s, parentPath);
}
else // 否则直接压缩文件
{
//打开压缩文件
using (FileStream fs = File.OpenRead(file))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
ZipEntry entry = new ZipEntry(fileName);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
}
}
}
///
/// 解压缩一个 zip 文件。
///
///要解压的 zip 文件。
///
///zip 文件的解压目录。
///
///zip 文件的密码。
///
///是否覆盖已存在的文件。
public static void UnZip(string zipedFile,
string strDirectory, string password, bool overWrite)
{
if (strDirectory == "")
strDirectory = Directory.GetCurrentDirectory();
if (!strDirectory.EndsWith("\\"))
strDirectory = strDirectory + "\\";
using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile)))
{
s.Password = password;
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = "";
string pathToZip = "";
pathToZip = theEntry.Name;
if (pathToZip != "")
directoryName = Path.GetDirectoryName(pathToZip) + "\\";
string fileName = Path.GetFileName(pathToZip);
Directory.CreateDirectory(strDirectory + directoryName);
if (fileName != "")
{
if ((File.Exists(strDirectory + directoryName + fileName) &&
overWrite) || (!File.Exists(strDirectory +
directoryName + fileName)))
{
using (FileStream streamWriter =
File.Create(strDirectory + directoryName + fileName))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
streamWriter.Write(data, 0, size);
else
break;
}
streamWriter.Close();
}
}
}
}
s.Close();
}
}
}
}
测试:
protected void Button1_Click(object sender, EventArgs e)
{
ZipHelper.ZipFile(@"E:\02.gif", @"E:\02.zip");
}
protected void Button3_Click(object sender, EventArgs e)
{
ZipHelper.ZipFile(@"E:\asp.net中文手册.chm", @"E:\asp.net中文手册.zip", 5, 1024);
}
protected void Button2_Click(object sender, EventArgs e)
{
ZipHelper.UnZip("E:\\页面窗口拖动.zip", "E:\\页面窗口拖动2\\", "", true);
}
protected void Button4_Click(object sender, EventArgs e)
{
ZipHelper.ZipFileDirectory("E:\\页面窗口拖动\\", "E:\\页面窗口拖动.zip");
}
在解压缩的时候会出现一个问题:size mismatch: XXXXXXX有个办法,我还没仔细看,但是有效:打开SharpZipLib源代码,你找到ZIP文件夹下的,ZipInputStream.cs文件然后找到这段
if ((flags & 8) == 0 && (inf.TotalIn != csize || inf.TotalOut != size))
{
throw new ZipException("Size mismatch: " + csize + ";" +
size + " <-> " + inf.TotalIn + ";" + inf.TotalOut);
} 把如上代码注释掉,然后编译,从新引入DLL到项目中就可以了.