利用SharpZipLib进行压缩和解压缩
因为工作需要所以要用C#写一个压缩解压缩的程序,从网上搜索大概有那么三种方式,1、调用winrar的接口函数来实现,缺点是必须安装winrar所以不具有通用性。2、msdn说的(使用 J# 类库中的 Zip 类压缩文件和数据)3、就是利用SharpZipLib进行压缩和解压缩这个是一家公司开发的可以用于封装在商业用途的软件中的.net类。下载地址
http://www.icsharpcode.net/ 从壓縮包里面将ICSharpCode.SharpZipLib.dll文件引入.net程序即可使用。在写这个类的时候参考了csdn一个网友写的类,他的类只能压缩活页夹下面的文件,而不能压缩子目录及其子目录下面的文件,解压的时候只能解压没有子目录的压缩包。所以我将它作了改进,使之能够压缩子目录及其文件和能够解压带有子目录及其文件的压缩包。下面是程序代码及其注释。
/**/
/// 以下为ZipClass即是压缩类
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace Webpos
{
public class ZipClass
{
public string cutStr = "";
这个函数我没有去研究他#region 这个函数我没有去研究他
public void ZipFile(string FileToZip, string ZipedFile ,int CompressionLevel, int BlockSize)
{
//如果文件没有找到则报错。
if (! System.IO.File.Exists(FileToZip))
{
throw new System.IO.FileNotFoundException("The specified file " + FileToZip + " could not be found. Zipping aborderd");
}
System.IO.FileStream StreamToZip = new System.IO.FileStream(FileToZip,System.IO.FileMode.Open , System.IO.FileAccess.Read);
System.IO.FileStream ZipFile = System.IO.File.Create(ZipedFile);
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
ZipEntry ZipEntry = new ZipEntry("ZippedFile");
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(CompressionLevel);
byte[] buffer = new byte[BlockSize];
System.Int32 size =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,size);
try
{
while (size < StreamToZip.Length)
{
int sizeRead =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,sizeRead);
size += sizeRead;
}
}
catch(System.Exception ex)
{
throw ex;
}
ZipStream.Finish();
ZipStream.Close();
StreamToZip.Close();
}
#endregion
//Get all DirectoryInfo
private void direct(DirectoryInfo di,ref ZipOutputStream s,Crc32 crc)
{
//DirectoryInfo di = new DirectoryInfo(filenames);
DirectoryInfo[] dirs = di.GetDirectories("*");
//遍历目录下面的所有的子目录
foreach(DirectoryInfo dirNext in dirs)
{
//将该目录下的所有文件添加到 ZipOutputStream s 压缩流里面
FileInfo[] a = dirNext.GetFiles();
this.writeStream( ref s,a,crc );
//递归调用直到把所有的目录遍历完成
direct(dirNext,ref s,crc);
}
}
private void writeStream(ref ZipOutputStream s,FileInfo[] a,Crc32 crc)
{
foreach ( FileInfo fi in a )
{
//string fifn = fi.FullName;
FileStream fs = fi.OpenRead();
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
//ZipEntry entry = new ZipEntry(file); Path.GetFileName(file)
string file = fi.FullName;
file = file.Replace(cutStr,"");
ZipEntry entry = new ZipEntry(file);
entry.DateTime = DateTime.Now;
// set Size and the crc, because the information
// about the size and crc should be stored in the header
// if it is not set it is automatically written in the footer.
// (in this case size == crc == -1 in the header)
// Some ZIP programs have problems with zip files that don't store
// the size and crc in the header.
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>
/// 主调函数
/// </summary>
/// <param name="args">args[0]为你要压缩的目录所在的路径
/// 例如:D://temp// (注意temp 后面加 // 但是你写程序的时候怎么修改都可以)
/// args[1]为压缩后的文件名及其路径
/// 例如:D://temp.zip
/// </param>
public void ZipFileMain(string[] args)
{
//string filenames = Directory.GetFiles(args[0]);
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
s.SetLevel(6); // 0 - store only to 9 - means best compression
DirectoryInfo di = new DirectoryInfo(args[0]);
FileInfo[] a = di.GetFiles();
cutStr = args[0].Trim();
//压缩这个目录下的所有文件
writeStream(ref s,a,crc);
//压缩这个目录下子目录及其文件
direct(di,ref s,crc);
s.Finish();
s.Close();
}
}
}
/**/ ///下面是解压缩文件的类
using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
namespace Webpos
{
public class UnZipClass
{
public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name);
//生成解压目录
Directory.CreateDirectory(directoryName);
if (fileName != String.Empty)
{
//如果文件的壓縮後的大小為0那麼說明這個文件是空的因此不需要進行讀出寫入
if( theEntry.CompressedSize == 0 )
break;
//解压文件到指定的目录
directoryName = Path.GetDirectoryName(args[1]+theEntry.Name);
//建立下面的目录和子目录
Directory.CreateDirectory(directoryName);
FileStream streamWriter = File.Create(args[1]+theEntry.Name);
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();
}
}
}
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace Webpos
{
public class ZipClass
{
public string cutStr = "";
这个函数我没有去研究他#region 这个函数我没有去研究他
public void ZipFile(string FileToZip, string ZipedFile ,int CompressionLevel, int BlockSize)
{
//如果文件没有找到则报错。
if (! System.IO.File.Exists(FileToZip))
{
throw new System.IO.FileNotFoundException("The specified file " + FileToZip + " could not be found. Zipping aborderd");
}
System.IO.FileStream StreamToZip = new System.IO.FileStream(FileToZip,System.IO.FileMode.Open , System.IO.FileAccess.Read);
System.IO.FileStream ZipFile = System.IO.File.Create(ZipedFile);
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
ZipEntry ZipEntry = new ZipEntry("ZippedFile");
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(CompressionLevel);
byte[] buffer = new byte[BlockSize];
System.Int32 size =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,size);
try
{
while (size < StreamToZip.Length)
{
int sizeRead =StreamToZip.Read(buffer,0,buffer.Length);
ZipStream.Write(buffer,0,sizeRead);
size += sizeRead;
}
}
catch(System.Exception ex)
{
throw ex;
}
ZipStream.Finish();
ZipStream.Close();
StreamToZip.Close();
}
#endregion
//Get all DirectoryInfo
private void direct(DirectoryInfo di,ref ZipOutputStream s,Crc32 crc)
{
//DirectoryInfo di = new DirectoryInfo(filenames);
DirectoryInfo[] dirs = di.GetDirectories("*");
//遍历目录下面的所有的子目录
foreach(DirectoryInfo dirNext in dirs)
{
//将该目录下的所有文件添加到 ZipOutputStream s 压缩流里面
FileInfo[] a = dirNext.GetFiles();
this.writeStream( ref s,a,crc );
//递归调用直到把所有的目录遍历完成
direct(dirNext,ref s,crc);
}
}
private void writeStream(ref ZipOutputStream s,FileInfo[] a,Crc32 crc)
{
foreach ( FileInfo fi in a )
{
//string fifn = fi.FullName;
FileStream fs = fi.OpenRead();
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
//ZipEntry entry = new ZipEntry(file); Path.GetFileName(file)
string file = fi.FullName;
file = file.Replace(cutStr,"");
ZipEntry entry = new ZipEntry(file);
entry.DateTime = DateTime.Now;
// set Size and the crc, because the information
// about the size and crc should be stored in the header
// if it is not set it is automatically written in the footer.
// (in this case size == crc == -1 in the header)
// Some ZIP programs have problems with zip files that don't store
// the size and crc in the header.
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>
/// 主调函数
/// </summary>
/// <param name="args">args[0]为你要压缩的目录所在的路径
/// 例如:D://temp// (注意temp 后面加 // 但是你写程序的时候怎么修改都可以)
/// args[1]为压缩后的文件名及其路径
/// 例如:D://temp.zip
/// </param>
public void ZipFileMain(string[] args)
{
//string filenames = Directory.GetFiles(args[0]);
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
s.SetLevel(6); // 0 - store only to 9 - means best compression
DirectoryInfo di = new DirectoryInfo(args[0]);
FileInfo[] a = di.GetFiles();
cutStr = args[0].Trim();
//压缩这个目录下的所有文件
writeStream(ref s,a,crc);
//压缩这个目录下子目录及其文件
direct(di,ref s,crc);
s.Finish();
s.Close();
}
}
}
/**/ ///下面是解压缩文件的类
using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
namespace Webpos
{
public class UnZipClass
{
public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name);
//生成解压目录
Directory.CreateDirectory(directoryName);
if (fileName != String.Empty)
{
//如果文件的壓縮後的大小為0那麼說明這個文件是空的因此不需要進行讀出寫入
if( theEntry.CompressedSize == 0 )
break;
//解压文件到指定的目录
directoryName = Path.GetDirectoryName(args[1]+theEntry.Name);
//建立下面的目录和子目录
Directory.CreateDirectory(directoryName);
FileStream streamWriter = File.Create(args[1]+theEntry.Name);
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();
}
}
}