using System;
using System.Collections.Generic;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
namespace System.IO
{
/// <summary>
/// ZIP 压缩包处理工具
/// </summary>
public static class ZIP
{
#region 压缩
/// <summary>
/// 压缩
/// </summary>
/// <param name="files">要压缩的流</param>
/// <returns></returns>
public static Stream Encode(Dictionary<string, Stream> files)
{
MemoryStream result = new MemoryStream(); //返回值
using (MemoryStream tmp = new MemoryStream()) //临时流
using (ZipOutputStream zip = new ZipOutputStream(tmp)) //ZIP操作对象
{
//设置压缩级别
zip.SetLevel(9);
//循环获取流对象
foreach (var key in files.Keys)
{
//创建单个压缩项
ZipEntry entry = new ZipEntry(key);
entry.DateTime = DateTime.Now; //设置创建时间
//加入单个压缩项
zip.PutNextEntry(entry);
#region 写入文件流
files[key].Position = 0;
int length = 4096;
byte[] buffer = new byte[length];
while ((length = files[key].Read(buffer, 0, buffer.Length)) > 0)
{
zip.Write(buffer, 0, length);
}
#endregion
//关闭压缩项
zip.CloseEntry();
}
zip.Flush(); //将缓冲区的全部输入
zip.Finish(); //结束压缩
tmp.Clone(result); //将临时流的数据复制到返回值中
zip.Close(); //关闭 ZIP 压缩操作
}
return result;
}
/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="path">文件夹地址</param>
/// <returns>ZIP保存地址</returns>
public static string Encode(string path)
{
DirectoryInfo dirInfo = new DirectoryInfo(path); //获取路径信息
string saveFileName = dirInfo.FullName + ".zip"; //以路径名为 zip 文件名
return Encode(path, saveFileName); //执行压缩操作并返回保存的文件名
}
/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="path">文件夹地址</param>
/// <param name="saveFile">ZIP保存地址</param>
/// <returns>ZIP保存地址</returns>
public static string Encode(string path, string saveFile)
{
var fileItems = FileNames(path); //获取路径下的所有文件名,文件名为带路径的文件名
string rootPathName = new DirectoryInfo(path).FullName + "\\"; //获取 ZIP 的根路径名,即要压缩的路径名称
using (FileStream fileStream = new FileStream(saveFile, FileMode.Create)) // ZIP 文件流操作对象
using (ZipOutputStream zip = new ZipOutputStream(fileStream)) // ZIP 压缩流操作对象
{
zip.SetLevel(9); //设置压缩级别
//循环所有文件
foreach (var fileName in fileItems)
{
//创建压缩项,压缩项的名称为文件名将根路径名称去除掉后的值
ZipEntry entry = new ZipEntry(fileName.Replace(rootPathName, ""));
entry.DateTime = DateTime.Now; //设置创建时间
//加入压缩项
zip.PutNextEntry(entry);
#region 读取文件流并写入 ZIP 压缩流
using (FileStream itemFileStream = new FileStream(fileName, FileMode.Open))
{
int length = 4096;
byte[] buffer = new byte[length];
while ((length = itemFileStream.Read(buffer, 0, buffer.Length)) > 0)
{
zip.Write(buffer, 0, length);
}
itemFileStream.Close();
}
#endregion
//关闭压缩项
zip.CloseEntry();
}
zip.Flush(); //清空缓冲区
zip.Finish(); //结束压缩操作
zip.Close(); //关闭压缩流
}
return saveFile;
}
#endregion
#region 解压
/// <summary>
/// 解压缩
/// </summary>
/// <param name="source">ZIP 流</param>
/// <returns></returns>
public static Dictionary<string, Stream> Descode(Stream source)
{
//返回值
Dictionary<string, Stream> result = new Dictionary<string, Stream>();
//创建 ZIP 解压流操作对象
using (ZipInputStream zip = new ZipInputStream(source))
{
//压缩项
ZipEntry entry = null;
while ((entry = zip.GetNextEntry()) != null) //循环获取压缩项,为空的话表示没有下一个
{
string key = entry.Name; //获取压缩项名称
MemoryStream stream = new MemoryStream(); //单项的解压后的流
int length = 4096; //缓冲大小
byte[] buffer = new byte[length]; //缓冲字节码
while ((length = zip.Read(buffer, 0, buffer.Length)) > 0) //循环读取解压操作流到缓冲字节码中
{
stream.Write(buffer, 0, length); //将缓冲字节码写入解压流
}
stream.Position = 0; //将解压流的操作位置归零
result.Add(key, stream); //添加到结果集中
}
}
return result;
}
/// <summary>
/// 解压缩 ZIP 文件
/// </summary>
/// <param name="fileName">ZIP文件</param>
/// <returns>解压后的保存地址</returns>
public static string Descode(string fileName)
{
var fileInfo = new FileInfo(fileName); //ZIP文件信息对象
string dirName = fileInfo.FullName.Replace(fileInfo.Extension, ""); //获取ZIP文件所在路径并设置解压保存路径与 ZIP 文件名一样
return Descode(fileName, dirName); //解压 ZIP 并返回保存的路径
}
/// <summary>
/// 解压缩 ZIP 文件
/// </summary>
/// <param name="fileName">ZIP文件</param>
/// <param name="dirName">解压后的保存地址</param>
/// <returns>解压后的保存地址</returns>
public static string Descode(string fileName, string dirName)
{
var fileInfo = new FileInfo(fileName); //获取 ZIP 文件信息
if (Directory.Exists(dirName)) Directory.Delete(dirName); //若保存目录存在则删除
using (FileStream fileStream = new FileStream(fileName, FileMode.Open)) //ZIP 文件操作流
using (ZipInputStream zip = new ZipInputStream(fileStream)) //ZIP 解压流
{
ZipEntry entry = null; //单个压缩项
while ((entry = zip.GetNextEntry()) != null) //循环获取单个压缩项,为空的话就没有下一项
{
string itemFileName = dirName + "\\" + entry.Name; //设置单项解压文件的文件名
string itemDir = Path.GetDirectoryName(itemFileName); //设置单项解压文件的路径名
if (!Directory.Exists(itemDir)) Directory.CreateDirectory(itemDir); //若路径不存在,则创建
//写入单个解压文件
using (FileStream itemFileStream = new FileStream(itemFileName, FileMode.Create))
{
int length = 4096; //缓冲字节码长度
byte[] buffer = new byte[length]; //缓冲字节码
while ((length = zip.Read(buffer, 0, buffer.Length)) > 0) //循环读取缓冲字节码
{
itemFileStream.Write(buffer, 0, length); //将缓冲字节码写入单项解压文件中
}
itemFileStream.Flush(); //清空单项解压文件的缓冲区
itemFileStream.Close(); //关闭单项解压文件的操作流
}
}
}
//返回保存路径名
return dirName;
}
#endregion
#region 内部使用的辅助函数
/// <summary>
/// 获取给定路径下的所有文件,包含子路径的文件,文件名为全路径地址
/// </summary>
/// <param name="path">要获取文件的路径名</param>
/// <returns>该路径下的所有文件</returns>
private static string[] FileNames(string path)
{
List<string> result = new List<string>(); //返回值
var dis = System.IO.Directory.GetDirectories(path); //获取当前路径的子目录
foreach (var dic in dis) //循环子目录
{
result.AddRange(FileNames(dic)); //递归获取子目录的文件
}
var files = System.IO.Directory.GetFiles(path); //获取当前路径下的所有文件
if (files != null && files.Length > 0) //若当前路径下有文件
{
result.AddRange(files); //将当前路径下的所有文件添加到返回值中
}
return result.ToArray(); //返回当前路径下的所有文件
}
/// <summary>
/// 复制流
/// </summary>
/// <param name="source">源流</param>
/// <param name="target">目标流</param>
private static void Clone(this Stream source, Stream target)
{
int length = 4096; //设置缓冲字节码大小
byte[] buffer = new byte[length]; //缓冲字节码
source.Position = 0; //将源流操作地址归零
while ((length = source.Read(buffer, 0, buffer.Length)) > 0) //读取源流到缓冲区
{
target.Write(buffer, 0, length); //将缓冲区写入目标流
}
target.Flush(); //清空目标流的缓冲区
source.Position = 0; //源流操作地址归零
target.Position = 0; //目标流操作地址归零
}
#endregion
}
}
这个工具类的调用DLL名称为:ICSharpCode.SharpZipLib.dll
以上功能亲测过,都能正常使用。
新人发表,欢迎大家点评