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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM