ZIP壓縮工具C#小程序實現 支持多個文件和文件夾

jopen 10年前發布 | 28K 次閱讀 ZIP .NET開發

 C# ZIP壓縮工具小程序實現 支持多個文件和文件夾

主要用到了一個SharpLibZip.dll庫

1、內部算法 -- 支持多個文件和文件夾

using System; using System.Collections.Generic; using System.Text; using System.IO; using ICSharpCode.SharpZipLib; using ICSharpCode.SharpZipLib.Zip; using ICSharpCode.SharpZipLib.Checksums;

namespace ZipUnZipLib{

 // <summary>
 /// 壓縮類
 /// </summary>
public class ZipClass
{
     /// <summary>
     /// 遞歸壓縮文件夾方法
     /// </summary>
     /// <param name="FolderToZip"></param>
     /// <param name="s"></param>
     /// <param name="ParentFolderName"></param>
     private   bool ZipFileDictory(string FolderToZip, ZipOutputStream s, string ParentFolderName)
      {
         bool res = true;
         string[] folders, filenames;
         ZipEntry entry = null;
         FileStream fs = null;
         Crc32 crc = new Crc32();
         try{
             //創建當前文件夾
             entry = new ZipEntry(Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip) + "/")); //加上 “/” 才會當成是文件夾創建
             s.PutNextEntry(entry);
             s.Flush();
            //先壓縮文件,再遞歸壓縮文件夾
             filenames = Directory.GetFiles(FolderToZip);
             foreach (string file in filenames){
                 //打開壓縮文件
                 fs = File.OpenRead(file);
                 byte[] buffer = new byte[fs.Length];
                 fs.Read(buffer, 0, buffer.Length);
                 entry = new ZipEntry(Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip) + "/" + Path.GetFileName(file)));
                 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);
             }
         }catch{
            res = false;
         }finally{
             if (fs != null)
             {
                fs.Close();
                fs = null;
             }
             if (entry != null)
             {
              entry = null;
             }
             GC.Collect();
             GC.Collect(1);
         }

         folders = Directory.GetDirectories(FolderToZip);

         foreach (string folder in folders){
            if (!ZipFileDictory(folder, s, Path.Combine(ParentFolderName, Path.GetFileName(FolderToZip)))){
                return false;
            }
         }
         return res;
     }

     /// <summary>
     /// 壓縮目錄
     /// </summary>
     /// <param name="FolderToZip">待壓縮的文件夾,全路徑格式</param>
     /// <param name="ZipedFile">壓縮后的文件名,全路徑格式</param>
     /// <param name="Password">壓宿密碼</param>
     /// <returns></returns>
     private bool ZipFileDictory(string FolderToZip, string ZipedFile, String Password){
        bool res;
        if (!Directory.Exists(FolderToZip)){
           return false;
        }
        ZipOutputStream s = new ZipOutputStream(File.Create(ZipedFile));
        s.SetLevel(6);
        s.Password = Password;
        res = ZipFileDictory(FolderToZip, s, "");
        s.Finish();
        s.Close();
        return res;
     }


     /// <summary>
     /// 壓縮多個目錄或文件
     /// </summary>
     /// <param name="FolderToZip">待壓縮的文件夾,全路徑格式</param>
     /// <param name="ZipedFile">壓縮后的文件名,全路徑格式</param>
     /// <param name="Password">壓宿密碼</param>
     /// <returns></returns>
     private bool ZipManyFilesDictorys(string FolderToZip, string ZipedFile, String Password) {
         //多個文件分開
         string[] filsOrDirs = FolderToZip.Split('%');
         bool res = true ;
         ZipOutputStream s = new ZipOutputStream(File.Create(ZipedFile));
         s.SetLevel(6);
         s.Password = Password;
         foreach (string fileOrDir in filsOrDirs){
             //是文件夾
             if (Directory.Exists(fileOrDir))
             {
                 res = ZipFileDictory(fileOrDir, s, "");
             }
             else  //文件
             {
                 res = ZipFileWithStream(fileOrDir, s, "");
             }
         }
         s.Finish();
         s.Close();
         return res;
     }


     /// <summary>
     /// 帶壓縮流壓縮單個文件
     /// </summary>
     /// <param name="FileToZip">要進行壓縮的文件名</param>
     /// <param name="ZipedFile">壓縮后生成的壓縮文件名</param>
     /// <param name="Password">壓宿密碼</param>
     /// <returns></returns>
     private bool ZipFileWithStream(string FileToZip, ZipOutputStream ZipStream, String Password)
     {
         //如果文件沒有找到,則報錯
         if (!File.Exists(FileToZip))
         {
             throw new System.IO.FileNotFoundException("指定要壓縮的文件: " + FileToZip + " 不存在!");
         }
         //FileStream fs = null;
         FileStream ZipFile = null;
         ZipEntry ZipEntry = null;
         bool res = true;
         try
         {
             ZipFile = File.OpenRead(FileToZip);
             byte[] buffer = new byte[ZipFile.Length];
             ZipFile.Read(buffer, 0, buffer.Length);
             ZipFile.Close();
             ZipEntry = new ZipEntry(Path.GetFileName(FileToZip));
             ZipStream.PutNextEntry(ZipEntry);
             ZipStream.Write(buffer, 0, buffer.Length);
         }
         catch
         {
             res = false;
         }
         finally
         {
             if (ZipEntry != null)
             {
                 ZipEntry = null;
             }

             if (ZipFile != null)
             {
                 ZipFile.Close();
                 ZipFile = null;
             }
             GC.Collect();
             GC.Collect(1);
         }
         return res;

     }

     /// <summary>
     /// 壓縮文件
     /// </summary>
     /// <param name="FileToZip">要進行壓縮的文件名</param>
     /// <param name="ZipedFile">壓縮后生成的壓縮文件名</param>
     /// <param name="Password">壓宿密碼</param>
     /// <returns></returns>
     private  bool ZipFile(string FileToZip, string ZipedFile, String Password){

        //如果文件沒有找到,則報錯
         if (!File.Exists(FileToZip)){
             throw new System.IO.FileNotFoundException("指定要壓縮的文件: " + FileToZip + " 不存在!");
        }
        //FileStream fs = null;
         FileStream ZipFile = null;
         ZipOutputStream ZipStream = null;
         ZipEntry ZipEntry = null;
         bool res = true;
         try{
             ZipFile = File.OpenRead(FileToZip);
             byte[] buffer = new byte[ZipFile.Length];
             ZipFile.Read(buffer, 0, buffer.Length);
             ZipFile.Close();
             ZipFile = File.Create(ZipedFile);
             ZipStream = new ZipOutputStream(ZipFile);
             ZipStream.Password = Password;
             ZipEntry = new ZipEntry(Path.GetFileName(FileToZip));
             ZipStream.PutNextEntry(ZipEntry);
             ZipStream.SetLevel(6);
             ZipStream.Write(buffer, 0, buffer.Length);
         }catch {
            res = false;
         }finally{
            if (ZipEntry != null){
                ZipEntry = null;
             }
             if (ZipStream != null){
                 ZipStream.Finish();
                 ZipStream.Close();
             }
             if (ZipFile != null){
                 ZipFile.Close();
                 ZipFile = null;
             }
             GC.Collect();
             GC.Collect(1);
        }
        return res;
    }



    /// <summary>
    /// 壓縮文件 和 文件夾
    /// </summary>
    /// <param name="FileToZip">待壓縮的文件或文件夾,全路徑格式 多個用%號分隔</param>
    /// <param name="ZipedFile">壓縮后生成的壓縮文件名,全路徑格式</param>
    /// <returns></returns>
    public  bool Zip(String FileToZip, String ZipedFile, String Password){

        if (IsFilesOrFolders(FileToZip)){
            return ZipManyFilesDictorys(FileToZip, ZipedFile, Password);
        }else if (Directory.Exists(FileToZip)){  //單個文件夾
            return ZipFileDictory(FileToZip, ZipedFile, Password);
        }else if (File.Exists(FileToZip)){  //單個文件
            return ZipFile(FileToZip, ZipedFile, Password);
        }else{
           return false;
        }
     }

    //是否傳入的多個文件夾或文件或兩者都有
    private bool IsFilesOrFolders(string fileFolders){

        if (fileFolders.Split('%').Length > 1) {
            return true;
        }
        else{
            return false;
        }
    }
 }


/// <summary>
/// 解壓類=======================================
/// </summary>
public class UnZipClass
{
    /// <summary>
    /// 解壓功能(解壓壓縮文件到指定目錄)
    /// </summary>
    /// <param name="FileToUpZip">待解壓的文件</param>
    /// <param name="ZipedFolder">指定解壓目標目錄</param>
    /// <param name="Password">解壓密碼</param>
    public bool UnZip(string FileToUpZip, string ZipedFolder,string Password){

        if (!File.Exists(FileToUpZip)){
            return false;
        }
        if (!Directory.Exists(ZipedFolder)){
            Directory.CreateDirectory(ZipedFolder);
        }
        ZipInputStream s = null;
        ZipEntry theEntry = null;
        string fileName;
        FileStream streamWriter = null;
        try{
            s = new ZipInputStream(File.OpenRead(FileToUpZip));

            s.Password = Password;
            while ((theEntry = s.GetNextEntry()) != null){
                if (theEntry.Name != String.Empty){
                    fileName = Path.Combine(ZipedFolder, theEntry.Name);
                    ///判斷文件路徑是否是文件夾
                    if (fileName.EndsWith("/") || fileName.EndsWith("\")){
                        Directory.CreateDirectory(fileName);
                        continue;
                    }
                    streamWriter = File.Create(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;
                        }
                    }
                }
            }

            return true;
        }catch{
            //Console.WriteLine(ex.Message);
            return false;
        }finally{
            if (streamWriter != null){
                streamWriter.Close();
                streamWriter = null;
            }
            if (theEntry != null){
                theEntry = null;
            }
            if (s != null){
                s.Close();
                s = null;
            }
            GC.Collect();
            GC.Collect(1);
        }
    }


}

}

2、界面代碼Winform

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using ZipUnZipLib;

namespace ZipUnZipWinFrom { public partial class ZipForm : Form {

    private System.Collections.Specialized.StringCollection folderCol;
    private static ZipClass zipClass = new ZipClass();  //壓縮工具類
    private static UnZipClass unZipC = new UnZipClass();  //解壓縮類

    public ZipForm()
    {
        InitializeComponent();

        folderCol = new System.Collections.Specialized.StringCollection();
        CreateHeadersAndFiledListView();
        PaintListView(@"C:");
        folderCol.Add(@"C:");
    }



    private void ZipForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (MessageBox.Show("是否退出工具?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
            MessageBoxDefaultButton.Button2) == DialogResult.No)
        {
            e.Cancel = true;
        }
        else
        {
            e.Cancel = false;
        }
    }

    private void ZipForm_Load(object sender, EventArgs e)
    {

    }

    /// <summary>
    /// 添加列標題
    /// </summary>
    private void CreateHeadersAndFiledListView()
    {
        ColumnHeader colHead;
        colHead = new ColumnHeader();
        colHead.Text = "文件名";
        colHead.Width = 200;
        listViewFilesAndFolders.Columns.Add(colHead);

        colHead = new ColumnHeader();
        colHead.Text = "大小";
        colHead.Width = 80;
        listViewFilesAndFolders.Columns.Add(colHead);

        colHead = new ColumnHeader();
        colHead.Text = "類型";
        colHead.Width = 80;
        listViewFilesAndFolders.Columns.Add(colHead);

        colHead = new ColumnHeader();
        colHead.Text = "修改日期";
        colHead.Width = 200;
        listViewFilesAndFolders.Columns.Add(colHead);

    }

    /// <summary>
    /// 硬盤文件填充文件列表
    /// </summary>
    private void PaintListView( string root )
    {

        try {

            ListViewItem lvi;

            ListViewItem.ListViewSubItem lvis;

            if (string.IsNullOrEmpty(root))
                return;

            DirectoryInfo dir = new DirectoryInfo( root );
            DirectoryInfo[] dirs = dir.GetDirectories();
            FileInfo[] files = dir.GetFiles();

            listViewFilesAndFolders.Items.Clear();
            currentPath.Text = root;
            listViewFilesAndFolders.BeginUpdate();

            foreach( DirectoryInfo di in dirs )
            {
                lvi = new ListViewItem();
                lvi.Text = di.Name;
                lvi.ImageIndex = 0;
                lvi.Tag = dir.FullName;

                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = "";
                lvi.SubItems.Add(lvis);

                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = "文件夾";
                lvi.SubItems.Add(lvis);


                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = di.LastAccessTime.ToString();
                lvi.SubItems.Add(lvis);
                listViewFilesAndFolders.Items.Add(lvi);
            }

            foreach (FileInfo fi in files)
            {
                lvi = new ListViewItem();
                lvi.Text = fi.Name;
                lvi.ImageIndex = 1;
                lvi.Tag = dir.FullName;

                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = fi.Length.ToString()+" Byte";
                lvi.SubItems.Add(lvis);

                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = fi.Extension;
                lvi.SubItems.Add(lvis);


                lvis = new ListViewItem.ListViewSubItem();
                lvis.Text = fi.LastAccessTime.ToString();
                lvi.SubItems.Add(lvis);
                listViewFilesAndFolders.Items.Add(lvi);
            }


            listViewFilesAndFolders.EndUpdate();



        }catch( SystemException ex){
            MessageBox.Show("Exception + : "+ex.Message);
        }

    }

    private void listViewFilesAndFolders_ItemActivate(object sender, EventArgs e)
    {
        System.Windows.Forms.ListView lw = (System.Windows.Forms.ListView) sender;
        string fileName = lw.SelectedItems[0].Tag.ToString();

        string fullName = fileName +  lw.SelectedItems[0].Text + "\";


        if (lw.SelectedItems[0].ImageIndex != 0)
        {
            try
            {
                System.Diagnostics.Process.Start(fullName);
            }
            catch
            {
                return;
            }
        }
        else
        {
            PaintListView(fullName);
            folderCol.Add(fullName);
        }
    }

    /// <summary>
    /// 返回上一級文件夾
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
        if( folderCol.Count > 1 )
        {
            PaintListView(folderCol[folderCol.Count -2].ToString());
            folderCol.RemoveAt(folderCol.Count -1);
        }else{
            PaintListView(folderCol[0].ToString());
        }
    }


    private void LargeIcon_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rdb = (RadioButton)sender;

        if (rdb.Checked)
        {
            this.listViewFilesAndFolders.View = View.LargeIcon;
        }

    }

    private void SmallIcon_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rdb = (RadioButton)sender;

        if (rdb.Checked)
        {
            this.listViewFilesAndFolders.View = View.SmallIcon;
        }

    }

    private void List_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rdb = (RadioButton)sender;

        if (rdb.Checked)
        {
            this.listViewFilesAndFolders.View = View.List;
        }
    }

    private void Detail_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rdb = (RadioButton)sender;

        if (rdb.Checked)
        {
            this.listViewFilesAndFolders.View = View.Details;
        }

    }

    private void Title_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton rdb = (RadioButton)sender;

        if (rdb.Checked)
        {
            this.listViewFilesAndFolders.View = View.Tile;
        }
    }

    /// <summary>
    /// 瀏覽Windows文件夾
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, EventArgs e)
    {

        openSelectFolder();

    }

    /// <summary>
    /// 顯示信息提示
    /// </summary>
    /// <param name="title"></param>
    /// <param name="content"></param>
    private void showMsg( string title,string content)
    {
        MessageBox.Show(title+" "+content);

    }

    /// <summary>
    /// 取得列表中文件的全名(目錄+文件名)
    /// </summary>
    /// <returns></returns>
    private string getSelectedFileFullName()
    {
        string fileName = listViewFilesAndFolders.SelectedItems[0].Text;
        //文件夾目錄
        string dir = listViewFilesAndFolders.SelectedItems[0].Tag.ToString();
        //全路徑名
        string fullName = dir + fileName;

        return fullName;
    }

    //壓縮文件
    private void zipFile_Click(object sender, EventArgs e)
    {
        if (listViewFilesAndFolders.SelectedItems.Count > 0)
        {  
            //
            string selectFiles = this.getSelectFilesName();
            string zipToFile = SaveFileTextBox.Text;   //壓縮到哪個目錄下
            if (zipToFile == "")
            {
                showMsg("選擇解壓目標目錄", "");
                return;
            }
            //判斷保存的文件是否是Zip文件
            if (isZipFile(zipToFile))
            {
                if (zipClass.Zip(selectFiles, zipToFile, textBox1.Text))
                {

                    showMsg("壓縮成功", "");
                    //取得文件所在文件夾
                    string zipDir = this.getZipToDir(zipToFile);

                    PaintListView(zipDir + "\");
                    folderCol.Add(zipDir + "\");
                    SaveFileTextBox.Text = "";
                    textBox1.Text = "";
                }
                else {
                    showMsg("壓縮失敗", "");
                }
            }
            else
            {
                showMsg("請輸入正確的.zip文件(后綴.zip)", "");
            }
        }
        else
        {
            showMsg("請選擇操作文件", "");
        }
    }

    /// <summary>
    /// 取得傳入文件的目錄
    /// </summary>
    /// <returns></returns>
    private string getZipToDir(string zipToFile)
    {
        FileInfo finleInfo = new FileInfo(zipToFile);
        return finleInfo.DirectoryName;

    }
    /// <summary>
    /// 取得所有選擇的等壓縮的文件
    /// </summary>
    /// <returns></returns>

    private string getSelectFilesName()
    {
        string files = "";

        for (int i = 0; i < listViewFilesAndFolders.SelectedItems.Count; i++)
        {
            string fileName = listViewFilesAndFolders.SelectedItems[i].Text;
            //文件夾目錄
            string dir = listViewFilesAndFolders.SelectedItems[i].Tag.ToString();
            //全路徑名
            string fullName = dir + fileName;
            //選擇一個直接返回
            if (listViewFilesAndFolders.SelectedItems.Count == 1)
            {
                return fullName;
            }
            if (i < listViewFilesAndFolders.SelectedItems.Count - 1)
            {
                files += fullName + "%";  //文件之間用%分開
            }
            else {
                files += fullName;
            }

        }

        return files;

    }


    /// <summary>
    /// 解壓選擇的文件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void UnZipFile_Click(object sender, EventArgs e)
    {
        if (listViewFilesAndFolders.SelectedItems.Count > 0)
        {

            string zipFile = this.getSelectedFileFullName();
            string unZipFileTo = SaveFileTextBox.Text;   //解壓到哪個目錄下
            if(unZipFileTo ==""){
                showMsg("選擇解壓目標目錄", "");
                return;
            }
            //判斷文件是否是Zip文件
            if (isZipFile(zipFile))
            {
                if (unZipC.UnZip(zipFile, unZipFileTo, textBox1.Text))
                {

                    showMsg("解壓成功", "");
                    PaintListView(unZipFileTo + "\");
                    folderCol.Add(unZipFileTo + "\");
                    SaveFileTextBox.Text = "";
                    textBox1.Text = "";
                }
                else {
                    showMsg("解壓失敗", "");
                }
            }
            else
            {
                showMsg("您選擇的文件不是ZIP壓縮文件","");
            }

            //showMsg("選擇了文件", this.getSelectedFileFullName());
        }
        else
        {
            showMsg("請選擇待解壓文件", "");
        }
    }

    //判斷是否是zip 文件
    private bool isZipFile(string zipFile){

        if (".zip" == zipFile.Substring(zipFile.Length - 4,4))
        {
            return true;
        }
        return false;

    }

    private void button3_Click(object sender, EventArgs e)
    {
        if (MessageBox.Show("是否退出工具?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
            MessageBoxDefaultButton.Button2) == DialogResult.Yes)
        {
            this.Close();
        }

    }

    private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (MessageBox.Show("是否退出工具?", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
           MessageBoxDefaultButton.Button2) == DialogResult.Yes)
        {
            this.Close();
        }
    }

    private void choiceSaveDir_Click(object sender, EventArgs e)
    {
        DialogResult dr = folderBrowserDialog1.ShowDialog();

        if (dr.ToString() == "OK") //打開了文件夾
        {
            string fullFileName = folderBrowserDialog1.SelectedPath;
            SaveFileTextBox.Text = fullFileName ;
        }
    }

    private void 打開文件夾ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        openSelectFolder();
    }

    /// <summary>
    /// 打開文件夾選擇文件夾
    /// </summary>
    private void openSelectFolder()
    {

        DialogResult dr = folderBrowserDialog1.ShowDialog();

        if (dr.ToString() == "OK") //打開了文件夾
        {
            string fullFileName = folderBrowserDialog1.SelectedPath;


            PaintListView(fullFileName + "\");
            folderCol.Add(fullFileName + "\");

            //currentPath.Text = folderBrowserDialog1.SelectedPath;
        }

    }
}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!