ZIP压缩工具C#小程序实现 支持多个文件和文件夹
jopen
11年前
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; } } } }