使用 C# 和 SharpZipLib 压缩文件夹
本文将介绍一种方法,该方法可用于从多个位置收集文件并将它们压缩到一个压缩文件夹中。
引言
本文将介绍一种方法,该方法可用于从多个位置收集文件并将它们压缩到一个压缩文件夹中。 如果需要收集多个文件,将它们压缩,然后对它们执行某些操作(例如将压缩文件上传到服务器位置以进行存储或处理),则示例项目中的代码可能很有用。 该应用程序使用 SharpZipLib
作为压缩函数的基础。
如前所述,示例代码依赖于 SharpZipLib
库。 可以从此位置下载这些库:.NET 的 Zip、GZip、BZip2 和 Tar 实现。 除了处理 ZIP 文件之外,该库还处理 TAR、GZIP 和 BZIP2 压缩。
解决方案
该解决方案包含一个项目。 该示例以单个 Windows Forms 项目的形式提供,该项目包含一个主窗体 (frmMain
)。 除了添加了 SharpZipLib
DLL(引用列表中的第一项)之外,所有引用都在默认配置中。 从 .NET 平台的开源项目 网站下载 DLL 后,该下载已安装到本地文件系统中,并使用“添加引用”对话框的“浏览”选项添加。 驱动应用程序所需的所有代码都包含在主窗体的代码文件中。
代码:压缩文件夹 - 主窗体
“压缩文件夹”项目是一个包含单个窗体的 Windows Forms 项目。 项目所需的所有 UI 和代码都包含在单个主窗体 (frmMain.cs) 中。 除了默认值之外,添加到项目的唯一引用是支持在项目中使用 SharpZipLib 所必需的那些。 导入、命名空间和类声明如下
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.ComponentModel;
using System.Windows.Forms;
using System.Management;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace CompressFolders
{
public partial class frmMain : Form
{
在类声明之后,下一个代码块是默认构造函数和空的窗体加载事件处理程序
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
}
下一个代码块用于处理“浏览”按钮的单击事件。 此按钮用于显示打开文件对话框,该对话框用于捕获用户想要包含在压缩文件夹中的文件夹的路径。 代码已注释,以便您可以通过阅读此代码块来查看对代码每个部分正在做什么的描述
/// <summary>
/// Select files for subsequent addition to the list of
/// files to be archived
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnBrowse_Click(object sender, EventArgs e)
{
// configure the open file dialog
openFileDialog1.Title = "Add File";
openFileDialog1.Filter = "All Files (*.*)|*.*";
openFileDialog1.FileName = "";
// return if the user cancels the operation
if (openFileDialog1.ShowDialog() == DialogResult.Cancel)
{
return;
}
// set a local variable to contain the file name
// captured from the open file dialog
string sFilePath;
sFilePath = openFileDialog1.FileName;
if (sFilePath == "")
return;
// make sure the file exists before adding
// its path to the list of files to be
// compressed
if (System.IO.File.Exists(sFilePath) == false)
return;
else
txtAddFile.Text = sFilePath;
}
下一个代码块用于添加先前方法(“浏览”按钮)选择的文件,并将其添加到要包含在压缩文件夹中的文件列表中。 同样,此代码段已注释,用于描述代码的每个部分的作用。
/// <summary>
/// Button click event handler used to add files from the browse
/// textbox to the listbox control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddFile_Click(object sender, EventArgs e)
{
// Check for content in the text box
if (txtAddFile.Text == string.Empty)
{
MessageBox.Show("Use the browse button to search for " +
"the file to be added.", "Missing File Name");
return;
}
// Only allow the file to be added if the file is not a duplicate
for (int i = 0; i < lstFilePaths.Items.Count; i++)
{
if (lstFilePaths.Items[i].ToString() ==
txtAddFile.Text.ToString())
{
MessageBox.Show("That file has already been added to the
list.", "Duplicate");
return;
}
}
// Add the file to the listbox list
if (txtAddFile.Text != string.Empty)
lstFilePaths.Items.Add(txtAddFile.Text.ToString());
// clear the textbox and move the focus back to the textbox
txtAddFile.Text = string.Empty;
txtAddFile.Focus();
}
下一个代码段是“删除”按钮的单击事件处理程序。 此方法允许用户在使用“浏览”按钮和“添加”按钮添加项目后,从列表框列表中删除项目。
/// <summary>
/// Button click handler to remove selected items from
/// the listbox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnRemoveFile_Click(object sender, EventArgs e)
{
try
{
lstFilePaths.Items.Remove(lstFilePaths.SelectedItem);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
接下来是一个按钮事件处理程序,该处理程序使用“文件夹浏览器对话框”控件来帮助用户为完成的 ZIP 文件指定目标路径。
/// <summary>
/// Button click handler used to set the path to
/// the zipped file
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSaveBrowse_Click(object sender, EventArgs e)
{
// clear the folder path
txtSaveTo.Text = string.Empty;
// Show the FolderBrowserDialog.
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
txtSaveTo.Text = folderBrowserDialog1.SelectedPath;
}
}
下一个按钮单击事件处理程序包含用于收集标记的文件并将它们压缩到设置的目标文件夹的代码。 该代码将收集标识的文件,将文件复制到目标文件夹内的临时文件夹中,将它们压缩,然后删除临时文件夹。 此代码也已注释,您可以查看代码块中包含的注释,以阅读有关每个阶段发生的情况的描述。
/// <summary>
/// Collect the files into a common folder location, zip the
/// files up, and delete the copied files and folder
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{
// make sure there are files to zip
if (lstFilePaths.Items.Count < 1)
{
MessageBox.Show("There are not files queued for the zip
operation", "Empty File Set");
return;
}
// make sure there is a destination defined
if (txtSaveTo.Text == string.Empty)
{
MessageBox.Show("No destination file has been defined.",
"Save To Empty");
return;
}
lblUpdate.Visible = true;
lblUpdate.Refresh();
// name the zip file whatever the folder is named
// by splitting the file path to get the folder name
string[] sTemp = txtSaveTo.Text.Split('\\');
string sZipFileName = sTemp[sTemp.Length - 1].ToString();
// check to see if zipped file already exists
// user may rename it in the text box if it does.
FileInfo fi = new FileInfo(txtSaveTo.Text + '\\' + sZipFileName +".zip");
if (fi.Exists)
{
// move it to the folder
try
{
StringBuilder sb = new StringBuilder();
sb.Append("The file " + sZipFileName + " already exists.
");
sb.Append("You may rename it in the save to text box.");
MessageBox.Show(sb.ToString(), "Existing File Name");
txtSaveTo.Focus();
return;
}
catch
{
MessageBox.Show("Rename the file or select a new
location.", "File Error");
return;
}
}
// Check for the existence of the target folder and
// create it if it does not exist
if (!System.IO.Directory.Exists(txtSaveTo.Text +
"\\TempZipFile\\"))
{
System.IO.Directory.CreateDirectory(txtSaveTo.Text +
"\\TempZipFile\\");
}
// Set up a string to hold the path to the temp folder
string sTargetFolderPath = (txtSaveTo.Text + "\\TempZipFile\\");
// Process the files and move each into the target folder
for (int i = 0; i < lstFilePaths.Items.Count; i++)
{
string filePath = lstFilePaths.Items[i].ToString();
FileInfo fi2 = new FileInfo(filePath);
if (fi2.Exists)
{
// move it to the folder
try
{
fi2.CopyTo(sTargetFolderPath + fi2.Name, true);
}
catch
{
// clean up if the operation failed
System.IO.Directory.Delete(sTargetFolderPath);
MessageBox.Show("Could not copy files to temp
folder.", "File Error");
return;
}
}
}
// zip up the files
try
{
lblUpdate.Visible = true;
lblUpdate.Refresh();
string[] filenames = Directory.GetFiles(sTargetFolderPath);
// Zip up the files - From SharpZipLib Demo Code
using (ZipOutputStream s = new
ZipOutputStream(File.Create(txtSaveTo.Text + "\\" +
sZipFileName + ".zip")))
{
s.SetLevel(9); // 0-9, 9 being the highest compression
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();
}
// remove the progress bar
lblUpdate.Visible = false;
// clean up files by deleting the temp folder and its content
System.IO.Directory.Delete(txtSaveTo.Text +
"\\TempZipFile\\", true);
// Notify user
MessageBox.Show("Zip file " + txtSaveTo.Text + " created.");
// empty everything
lstFilePaths.Items.Clear();
txtSaveTo.Text = string.Empty;
txtAddFile.Text = string.Empty;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Zip Operation
Error");
}
}
项目中剩余的唯一代码是用于终止应用程序的代码。
/// <summary>
/// Exit the application
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnExit_Click(object sender, EventArgs e)
{
this.Dispose();
}
}
}
这样就结束了对该项目中使用的代码的描述。
摘要
此示例演示如何使用 SharpZipLib 压缩文件夹。 在此示例中,该界面以独立桌面应用程序的形式提供。 本项目中描述的相同方法可以在大型应用程序的上下文中应用,该应用程序可能需要收集多个文件并将它们压缩到一个压缩文件夹中。 与所有事物一样,还有其他方法可以做同样的事情。 但是,考虑到 SharpZipLib 的可用性,这是一个相对简单的过程。