文件压缩和解压

时间:2022-06-02 00:15:02
        #region  单文件目录压缩和解压
protected void Button1_Click(object sender, EventArgs e)
{
ZipFile("D://MyTestFile", Server.MapPath("~/1.zip"));
}

protected void Button2_Click(object sender, EventArgs e)
{
unZipFile(Server.MapPath("~/1.zip"), Server.MapPath("~/"));
}

/// <summary>
/// 适用于单文件夹的压缩
/// </summary>
/// <param name="path">压缩文件路劲</param>
/// <param name="destFileName">目标路径</param>
public static void ZipFile(string path, string destFileName)
{
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(destFileName));// 创建压缩后文件
s.Password = ""; // 设置密码
s.SetLevel(6);//0-9
DirectoryInfo myDir = new DirectoryInfo(path);// 获取目录
if (myDir.Exists == true)
{
FileInfo[] myFileAry = myDir.GetFiles();

// 循环遍历文件夹下每一个文件
foreach (FileInfo objectFiles in myFileAry)
{
// 获取完整路径
FileStream fs = File.OpenRead(objectFiles.FullName);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(objectFiles.FullName.Split('\\')[objectFiles.FullName.Split('\\').Length - 1]);
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);
}
s.Finish();
s.Close();
}
}

/// <summary>
///
/// </summary>
/// <param name="sourceFileName">被解压文件名称</param>
/// <param name="destPath">解压后目录</param>
/// <param name="fileType">密码</param>
public static void unZipFile(string sourceFileName, string destPath)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(sourceFileName));
ZipEntry entry;
ArrayList arrayList = new ArrayList();
// 判断解压文件是否为空
while ((entry = s.GetNextEntry()) != null)
{
string fileName = Path.GetFileName(entry.Name);
if (fileName != "")
{
fileName = destPath + "\\" + fileName;
if (!Directory.Exists(destPath))
{
Directory.CreateDirectory(destPath);
}
FileStream stream = File.Create(fileName);
int size = 2048;
byte[] data = new byte[2048];
s.Password = "";
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
stream.Write(data, 0, size);
}
else
{
break;
}
}
stream.Close();
}
}
s.Close();
}

#endregion

#region 多文件压缩
protected void Button3_Click(object sender, EventArgs e)
{
string[] ss={Server.MapPath("~/B")};
Zip(Server.MapPath("~/m.zip"),Server.MapPath("~/"),4,"",ss);
}


/// <summary>
/// 获取所有文件
/// </summary>
/// <param name="parentDirectortPath">源文件路径</param>
/// <param name="AllFilesPath">所有文件路径</param>
public void GetDirectoryFiles(string parentDirectortPath, List<string> AllFilesPath)
{
string[] files = Directory.GetFiles(parentDirectortPath);
// 添加所有文件路径
for (int i = 0; i < files.Length; i++)
{
AllFilesPath.Add(files[i]);
}
string[] directorys = Directory.GetDirectories(parentDirectortPath);
// 递归遍历当然文件夹下的子文件夹
for (int i = 0; i < directorys.Length; i++)
{
GetDirectoryFiles(directorys[i],AllFilesPath);
}
if (files.Length == 0 &&directorys.Length == 0)
{
AllFilesPath.Add(parentDirectortPath);

}

}


/// <summary>
/// 生成压缩文件
/// </summary>
/// <param name="zipPath">zip路径</param>
/// <param name="sourceParentPath">源文件上级目录</param>
/// <param name="level">压缩等级</param>
/// <param name="password">密码</param>
/// <param name="filesOrDirectoriesPaths">源文件路径</param>
public void Zip(string zipPath, string sourceParentPath, int level, string password, string[] filesOrDirectoriesPaths)
{
List<string> allFilesPath = new List<string>();
// 获取所有文件
if (filesOrDirectoriesPaths.Length > 0)
{
for (int i = 0; i < filesOrDirectoriesPaths.Length; i++)
{
// 如果是文件直接添加 是目录 则遍历目录后添加
if (File.Exists(filesOrDirectoriesPaths[i]))
{
allFilesPath.Add(filesOrDirectoriesPaths[i]);
}
else if (Directory.Exists(filesOrDirectoriesPaths[i]))
{
GetDirectoryFiles(filesOrDirectoriesPaths[i],allFilesPath);
}
}
}
if (allFilesPath.Count > 0)
{
// ZipOutputStream s = new ZipOutputStream(File.Open(zipPath,FileMode.OpenOrCreate));
ZipOutputStream s = new ZipOutputStream(File.Create(zipPath));
s.SetLevel(level);
s.Password = password;
for (int i = 0; i < allFilesPath.Count; i++)
{
string strFile = allFilesPath[i].ToString();
if (strFile.Substring(strFile.Length - 1) == "")
{
string strFileName = strFile.Replace(sourceParentPath, "");
if (strFileName.StartsWith(""))
{
strFileName = strFileName.Substring(1);
ZipEntry entery = new ZipEntry(strFileName);
entery.DateTime = DateTime.Now;
s.PutNextEntry(entery);
}
}
else
{
FileStream fs = File.OpenRead(strFile);
byte[] buffer=new byte[fs.Length];
fs.Read(buffer,0,buffer.Length);
string strFileName = strFile.Replace(sourceParentPath,"");
if (strFileName.StartsWith(""))
{
strFileName = strFileName.Substring(0);
}
ZipEntry entry = new ZipEntry(strFileName);
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
s.Write(buffer,0,buffer.Length);
fs.Close();
fs.Dispose();

}
}
s.Finish();
s.Close();
}

}
#endregion


 

        private void  CompressFolder(string path,ZipOutputStream zipStream,int folderOffset)
{
// 获取文件夹中的文件
string[] files = Directory.GetFiles(path);
// 循环遍历
foreach (string filename in files)
{
FileInfo fi=new FileInfo(filename);
// 从文件夹名后开始截取
string entryName = filename.Substring(folderOffset);
entryName = ZipEntry.CleanName(entryName);
ZipEntry newEntry=new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime;
// newEntry.AESKeySize = 256; 使用AES则必须加上密码 128,256,0(off)
// zipStream.UseZip64 = UseZip64.Off;// 使 zip能在各版本中解压
newEntry.Size = fi.Length;

zipStream.PutNextEntry(newEntry);
byte[] buffer=new byte[4096];
using (FileStream streamReader=File.OpenRead(filename))
{
// 缓冲区从源文件复制到目标文件
StreamUtils.Copy(streamReader,zipStream,buffer);
}
zipStream.CloseEntry();
}
// 递归遍历目录
string[] folders = Directory.GetDirectories(path);
foreach (string folder in folders)
{
CompressFolder(folder,zipStream,folderOffset);
}
}

/// <summary>
/// 压缩文件
/// </summary>
/// <param name="outPathname">压缩后文件名</param>
/// <param name="password">密码</param>
/// <param name="folderName">要压缩的文件夹</param>
public void CreateSample(string outPathname,string password,string folderName)
{
FileStream fsout = File.Create(outPathname);
ZipOutputStream zipStream=new ZipOutputStream(fsout);
zipStream.SetLevel(3);
zipStream.Password = password;
int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);
CompressFolder(folderName,zipStream,folderOffset);
zipStream.IsStreamOwner = true; // 关闭相关流
zipStream.Close();
}

protected void Button3_Click(object sender, EventArgs e)
{
CreateSample(Server.MapPath("~/test.zip"),"",Server.MapPath("~/GG"));
}


private void DownloadZipToBrowser(List<string> zipFileList)
{

Response.ContentType = "application/zip";
// If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
// Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer.

Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition

byte[] buffer = new byte[4096];

ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
zipOutputStream.SetLevel(3); //0-9, 9 being the highest level of compression

foreach (string fileName in zipFileList)
{

Stream fs = File.OpenRead(fileName);// or any suitable inputstream

ZipEntry entry = new ZipEntry(ZipEntry.CleanName(fileName.Substring(fileName.LastIndexOf("\\"))));
entry.Size = fs.Length;
// Setting the Size provides WinXP built-in extractor compatibility,
// but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.

zipOutputStream.PutNextEntry(entry);

int count = fs.Read(buffer, 0, buffer.Length);
while (count > 0)
{
zipOutputStream.Write(buffer, 0, count);
count = fs.Read(buffer, 0, buffer.Length);
if (!Response.IsClientConnected)
{
break;
}
Response.Flush();
}
fs.Close();
}
zipOutputStream.Close();

Response.Flush();
Response.End();
}


protected void Button4_Click(object sender, EventArgs e)
{
List<string> list=new List<string>();
list.Add(Server.MapPath("~/test.zip"));
DownloadZipToBrowser(list);
}