波斯马BOSSMA Information Technology

c#使用开源项目[SharpZipLib]解压缩

发布时间:2009年2月14日 / 分类:ASP.NET, DOTNET / 30,367 次浏览 / 评论

一直还在使用.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
{
??? /// <summary>
??? /// Zip压缩与解压缩
??? /// 需要首先实例化,才能使用相关方法
??? /// </summary>
??? public class ZipHelper
??? {
??????? /// <summary>
??????? /// 压缩单个文件
??????? /// </summary>
??????? /// <param name="fileToZip">要压缩的文件</param>
??????? /// <param name="zipedFile">压缩后的文件</param>
??????? /// <param name="compressionLevel">压缩等级</param>
??????? /// <param name="blockSize">每次写入大小</param>
??????? public 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();
??????????? }
??????? }

??????? /// <summary>
??????? /// 压缩单个文件
??????? /// </summary>
??????? /// <param name="fileToZip">要进行压缩的文件名</param>
??????? /// <param name="zipedFile">压缩后生成的压缩文件名</param>
??????? public 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();
??????????????????? }
??????????????? }
??????????? }
??????? }

??????? /// <summary>
??????? /// 压缩多层目录
??????? /// </summary>
??????? /// <param name="strDirectory">The directory.</param>
??????? /// <param name="zipedFile">The ziped file.</param>
??????? public 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, "");
??????????????? }
??????????? }
??????? }

??????? /// <summary>
??????? /// 递归遍历目录
??????? /// </summary>
??????? /// <param name="strDirectory">The directory.</param>
??????? /// <param name="s">The ZipOutputStream Object.</param>
??????? /// <param name="parentPath">The parent path.</param>
??????? private 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)// 遍历所有的文件和目录
??????????? {

??????????????? if (Directory.Exists(file))// 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
??????????????? {
??????????????????? 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);
??????????????????? }
??????????????? }
??????????? }
??????? }

??????? /// <summary>
??????? /// 解压缩一个 zip 文件。
??????? /// </summary>
??????? /// <param name="zipedFile">The ziped file.</param>
??????? /// <param name="strDirectory">The STR directory.</param>
??????? /// <param name="password">zip 文件的密码。</param>
??????? /// <param name="overWrite">是否覆盖已存在的文件。</param>
??????? public 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到项目中就可以了.

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯马,原文地址《c#使用开源项目[SharpZipLib]解压缩

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】 【下一篇】

发表评论