C#压缩解压zip 文件

我在做项目的时候需要将文件进行压缩和解压缩,于是就从http://www.icsharpcode.net下载了关于压缩和解压缩的源码,但是下载下来后,面对这么多的代码,一时不知如何下手。只好耐下心来,慢慢的研究,总算找到了门路。针对自己的需要改写了文件压缩和解压缩的两个类,分别为ZipClass和UnZipClass。其中碰到了不少困难,就决定写出来压缩和解压的程序后,一定把源码贴出来共享,让首次接触压缩和解压缩的朋友可以少走些弯路。下面就来解释如何在C#里用http://www.icsharpcode.net下载的SharpZipLib进行文件的压缩和解压缩。

    首先需要在项目里引用SharpZipLib.dll。然后修改其中的关于压缩和解压缩的类。实现源码如下: 

  ///   <summary>
 
///  压缩文件
 
///   </summary>
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace Compression
{
  public  class ZipClass
 {
 
   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();
  }
 
   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
  
    foreach ( string file  in filenames) 
   {
     // 打开压缩文件
    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;
   
     //  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);
   
   }
  
   s.Finish();
   s.Close();
  }
 }
}
现在再来看看解压文件类的源码
  ///   <summary>
 
///  解压文件
 
///   </summary>
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 DeCompression
{
  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) 
    {   
      // 解压文件到指定的目录
     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();
  }
 }
}
    有了压缩和解压缩的类以后,就要在窗体里调用了。怎么?是新手,不会调用?Ok,接着往下看如何在窗体里调用。
    首先在窗体里放置两个命令按钮(不要告诉我你不会放啊~),然后编写以下源码
///   <summary>
 
///  调用源码
 
///   </summary>
       private  void button2_Click_1( object sender, System.EventArgs e)
  {
    string []FileProperties= new  string[ 2];
   FileProperties[ 0]= " C:\\unzipped\\ "; // 待压缩文件目录
   FileProperties[ 1]= " C:\\zip\\a.zip ";   // 压缩后的目标文件
   ZipClass Zc= new ZipClass();
   Zc.ZipFileMain(FileProperties);
  }
      private  void button2_Click( object sender, System.EventArgs e)
  {
    string []FileProperties= new  string[ 2];
   FileProperties[ 0]= " C:\\zip\\test.zip "; // 待解压的文件
   FileProperties[ 1]= " C:\\unzipped\\ "; // 解压后放置的目标目录
   UnZipClass UnZc= new UnZipClass();
   UnZc.UnZip(FileProperties);
  }
------------------------------------------------------------------------------------------------------------------
  ///   <summary>
 
///  压缩文件
 
///   </summary>
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace Compression
{
  public  class ZipClass
 {
 
   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();
  }
 
   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
  
    foreach ( string file  in filenames) 
   {
     // 打开压缩文件
    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;
   
     //  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);
   
   }
  
   s.Finish();
   s.Close();
  }
 }
}
现在再来看看解压文件类的源码
  ///   <summary>
 
///  解压文件
 
///   </summary>
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 DeCompression
{
  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) 
    {   
      // 解压文件到指定的目录
     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();
  }
 }
}
    有了压缩和解压缩的类以后,就要在窗体里调用了。怎么?是新手,不会调用?Ok,接着往下看如何在窗体里调用。
    首先在窗体里放置两个命令按钮(不要告诉我你不会放啊~),然后编写以下源码
///   <summary>
 
///  调用源码
 
///   </summary>
       private  void button2_Click_1( object sender, System.EventArgs e)
  {
    string []FileProperties= new  string[ 2];
   FileProperties[ 0]= " C:\\unzipped\\ "; // 待压缩文件目录
   FileProperties[ 1]= " C:\\zip\\a.zip ";   // 压缩后的目标文件
   ZipClass Zc= new ZipClass();
   Zc.ZipFileMain(FileProperties);
  }
      private  void button2_Click( object sender, System.EventArgs e)
  {
    string []FileProperties= new  string[ 2];
   FileProperties[ 0]= " C:\\zip\\test.zip "; // 待解压的文件
   FileProperties[ 1]= " C:\\unzipped\\ "; // 解压后放置的目标目录
   UnZipClass UnZc= new UnZipClass();
   UnZc.UnZip(FileProperties);
  }

 

示例二:

///   <summary>
///  Zip 压缩文件
///   </summary>
public  class Zip
{
     public Zip()
    {
        
    }
     #region 加压方法
     ///   <summary>
    
///  功能:压缩文件(暂时只压缩文件夹下一级目录中的文件,文件夹及其子级被忽略)
    
///   </summary>
    
///   <param name="dirPath"> 被压缩的文件夹夹路径 </param>
    
///   <param name="zipFilePath"> 生成压缩文件的路径,为空则默认与被压缩文件夹同一级目录,名称为:文件夹名+.zip </param>
    
///   <param name="err"> 出错信息 </param>
    
///   <returns> 是否压缩成功 </returns>
     public  static  bool ZipFile( string dirPath,  string zipFilePath,  out  string err)
    {
        err =  "";
         if (dirPath ==  string.Empty)
        {
            err =  " 要压缩的文件夹不能为空! ";
             return  false;
        }
         if (!Directory.Exists(dirPath))
        {
            err =  " 要压缩的文件夹不存在! ";
             return  false;
        }
         // 压缩文件名为空时使用文件夹名+.zip
         if (zipFilePath ==  string.Empty)
        {
             if (dirPath.EndsWith( " // "))
            {
                dirPath = dirPath.Substring( 0, dirPath.Length -  1);
            }
            zipFilePath = dirPath +  " .zip ";
        }

         try
        {
             string[] filenames = Directory.GetFiles(dirPath);
             using (ZipOutputStream s =  new ZipOutputStream(File.Create(zipFilePath)))
            {
                s.SetLevel( 9);
                 byte[] buffer =  new  byte[ 4096];
                 foreach ( string file  in filenames)
                {
                    ZipEntry entry =  new ZipEntry(Path.GetFileName(file));
                    entry.DateTime = DateTime.Now;
                    s.PutNextEntry(entry);
                     using (FileStream fs = File.OpenRead(file))
                    {
                         int sourceBytes;
                         do
                        {
                            sourceBytes = fs.Read(buffer,  0, buffer.Length);
                            s.Write(buffer,  0, sourceBytes);
                        }  while (sourceBytes >  0);
                    }
                }
                s.Finish();
                s.Close();
            }
        }
         catch (Exception ex)
        {
            err = ex.Message;
             return  false;
        }
         return  true;
    }
     #endregion 

     #region 解压
     ///   <summary>
    
///  功能:解压zip格式的文件。
    
///   </summary>
    
///   <param name="zipFilePath"> 压缩文件路径 </param>
    
///   <param name="unZipDir"> 解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹 </param>
    
///   <param name="err"> 出错信息 </param>
    
///   <returns> 解压是否成功 </returns>
     public  static  bool UnZipFile( string zipFilePath,  string unZipDir,  out  string err)
    {
        err =  "";
         if (zipFilePath ==  string.Empty)
        {
            err =  " 压缩文件不能为空! ";
             return  false;
        }
         if (!File.Exists(zipFilePath))
        {
            err =  " 压缩文件不存在! ";
             return  false;
        }
         // 解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
         if (unZipDir ==  string.Empty)
            unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
         if (!unZipDir.EndsWith( " // "))
            unZipDir +=  " // ";
         if (!Directory.Exists(unZipDir))
            Directory.CreateDirectory(unZipDir);

         try
        {
             using (ZipInputStream s =  new ZipInputStream(File.OpenRead(zipFilePath)))
            {

                ZipEntry theEntry;
                 while ((theEntry = s.GetNextEntry()) !=  null)
                {
                     string directoryName = Path.GetDirectoryName(theEntry.Name);
                     string fileName = Path.GetFileName(theEntry.Name);
                     if (directoryName.Length >  0)
                    {
                        Directory.CreateDirectory(unZipDir + directoryName);
                    }
                     if (!directoryName.EndsWith( " // "))
                        directoryName +=  " // ";
                     if (fileName != String.Empty)
                    {
                         using (FileStream streamWriter = File.Create(unZipDir + 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;
                                }
                            }
                        }
                    }
                } // while
            }
        }
         catch (Exception ex)
        {
            err = ex.Message;
             return  false;
        }
         return  true;
    } // 解压结束
     #endregion

------------------------------------------------------------------------------------------------------------ 

C#自带源码:http://files.cnblogs.com/greatverve/Compress.rar
------------------------------------------------------------------------------------------------------------

System.IO.Compression 命名空间  
  注意:此命名空间在 .NET Framework 2.0 版中是新增的。 
System.IO.Compression 命名空间包含提供基本的流压缩和解压缩服务的类。 
(downmoon原作)
  类                               说明 
 DeflateStream         提供用于使用 Deflate 算法压缩和解压缩流的方法和属性。 
 GZipStream             提供用于压缩和解压缩流的方法和属性。 
  枚举                         说明 
 CompressionMode 指定是否压缩或解压缩基础流。 

下面以 GZipStream  为例说明 


注意:此类在 .NET Framework 2.0 版中是新增的。 

提供用于压缩和解压缩流的方法和属性。 
命名空间:System.IO.Compression
程序集:System(在 system.dll 中)
语法
Visual Basic(声明) 
Public Class GZipStream
    Inherits Stream
 Visual Basic(用法) 
Dim instance As GZipStream
 
C# 
public class GZipStream : Stream
 
C++ 
public ref class GZipStream : public Stream
 
J# 
public class GZipStream extends Stream
 
JScript 
public class GZipStream extends Stream
 

备注
此 类表示 GZip 数据格式,它使用无损压缩和解压缩文件的行业标准算法。这种格式包括一个检测数据损坏的循环冗余校验值。GZip 数据格式使用的算法与 DeflateStream 类的算法相同,但它可以扩展以使用其他压缩格式。这种格式可以通过不涉及专利使用权的方式轻松实现。gzip 的格式可以从 RFC 1952“GZIP file format specification 4.3(GZIP 文件格式规范 4.3)GZIP file format specification 4.3(GZIP 文件格式规范 4.3)”中获得。此类不能用于压缩大于 4 GB 的文件。

给继承者的说明 当从 GZipStream 继承时,必须重写下列成员:CanSeek、CanWrite 和 CanRead。 


下面提供 一个完整的压缩与解压类(downmoon原作 ):

 
class  clsZip
    
{
        
public void CompressFile ( string sourceFile, string destinationFile )
        
{
            
// make sure the source file is there
            if ( File.Exists ( sourceFile ) == false )
                
throw new FileNotFoundException ( );

            
// Create the streams and byte arrays needed
            byte[] buffer = null;
            FileStream sourceStream = null;
            FileStream destinationStream = null;
            GZipStream compressedStream = null;

            
try
            
{
                
// Read the bytes from the source file into a byte array
                sourceStream = new FileStream ( sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read );

                
// Read the source stream values into the buffer
                buffer = new byte[sourceStream.Length];
                
int checkCounter = sourceStream.Read ( buffer, 0, buffer.Length );

                
if ( checkCounter != buffer.Length )
                
{
                    
throw new ApplicationException ( );
                }


                
// Open the FileStream to write to
                destinationStream = new FileStream ( destinationFile, FileMode.OpenOrCreate, FileAccess.Write );

                
// Create a compression stream pointing to the destiantion stream
                compressedStream = new GZipStream ( destinationStream, CompressionMode.Compress, true );

                
// Now write the compressed data to the destination file
                compressedStream.Write ( buffer, 0, buffer.Length );
            }

            
catch ( ApplicationException ex )
            
{
                MessageBox.Show ( ex.Message, "压缩文件时发生错误:", MessageBoxButtons.OK, MessageBoxIcon.Error );
            }

            
finally
            
{
                
// Make sure we allways close all streams
                if ( sourceStream != null )
                    sourceStream.Close ( );

                
if ( compressedStream != null )
                    compressedStream.Close ( );

                
if ( destinationStream != null )
                    destinationStream.Close ( );
            }

        }


        
public void DecompressFile ( string sourceFile, string destinationFile )
        
{
            
// make sure the source file is there
            if ( File.Exists ( sourceFile ) == false )
                
throw new FileNotFoundException ( );

            
// Create the streams and byte arrays needed
            FileStream sourceStream = null;
            FileStream destinationStream = null;
            GZipStream decompressedStream = null;
            
byte[] quartetBuffer = null;

            
try
            
{
                
// Read in the compressed source stream
                sourceStream = new FileStream ( sourceFile, FileMode.Open );

                
// Create a compression stream pointing to the destiantion stream
                decompressedStream = new GZipStream ( sourceStream, CompressionMode.Decompress, true );

                
// Read the footer to determine the length of the destiantion file
                quartetBuffer = new byte[4];
                
int position = (int)sourceStream.Length - 4;
                sourceStream.Position = position;
                sourceStream.Read ( quartetBuffer, 04 );
                sourceStream.Position = 0;
                
int checkLength = BitConverter.ToInt32 ( quartetBuffer, 0 );

                
byte[] buffer = new byte[checkLength + 100];

                
int offset = 0;
                
int total = 0;

                
// Read the compressed data into the buffer
                while ( true )
                
{
                    
int bytesRead = decompressedStream.Read ( buffer, offset, 100 );

                    
if ( bytesRead == 0 )
                        
break;

                    offset += bytesRead;
                    total += bytesRead;
                }


                
// Now write everything to the destination file
                destinationStream = new FileStream ( destinationFile, FileMode.Create );
                destinationStream.Write ( buffer, 0, total );

                
// and flush everyhting to clean out the buffer
                destinationStream.Flush ( );
            }

            
catch ( ApplicationException ex )
            
{
                MessageBox.Show(ex.Message, "解压文件时发生错误:", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            
finally
            
{
                
// Make sure we allways close all streams
                if ( sourceStream != null )
                    sourceStream.Close ( );

                
if ( decompressedStream != null )
                    decompressedStream.Close ( );

                
if ( destinationStream != null )
                    destinationStream.Close ( );
            }


        }

    }

 

url: http://greatverve.cnblogs.com/archive/2011/12/26/csharp-zip.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值