using ICSharpCode.SharpZipLib.Checksum;
using ICSharpCode.SharpZipLib.Zip;
using System.Text;
namespace YLErp.Helpers
{
public static class ZipHelper
{
static ZipHelper()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
ZipStrings.CodePage = Encoding.GetEncoding("gb2312").CodePage;
}
///
/// 压缩文件目录
///
///
///
public static void ZipDirectory(string sourceDir, string targetZipFile)
{
if (sourceDir[sourceDir.Length - 1] != Path.DirectorySeparatorChar)
{
sourceDir += Path.DirectorySeparatorChar;
}
var outstream = new ZipOutputStream(File.Create(targetZipFile));
outstream.SetLevel(6);
ZipDirectory(sourceDir, outstream, sourceDir);
outstream.Finish();
outstream.Close();
}
///
/// 压缩文件目录
///
///
///
///
public static void ZipDirectory(string sourceDir, ZipOutputStream outStream, string staticFile)
{
if (sourceDir[sourceDir.Length - 1] != Path.DirectorySeparatorChar)
{
sourceDir += Path.DirectorySeparatorChar;
}
//获取指定目录下所有文件和子目录文件名称
var filenames = Directory.GetFileSystemEntries(sourceDir);
zip(filenames, outStream, staticFile);
}
public static void zipFile(string strFile, string strZip)
{
var len = strFile.Length;
var strlen = strFile[len - 1];
if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar)
{
strFile += Path.DirectorySeparatorChar;
}
var outstream = new ZipOutputStream(File.Create(strZip));
outstream.SetLevel(6);
zip(strFile, outstream, strFile);
outstream.Finish();
outstream.Close();
}
public static void zipOnlyFile(string strFile, string strZip, string password = "")
{
var outstream = new ZipOutputStream(File.Create(strZip));
outstream.SetLevel(6);
if (!string.IsNullOrWhiteSpace(password))
{
outstream.Password = password;
}
string[] filenames = new string[] { strFile };
zip(filenames, outstream, strFile);
outstream.Finish();
outstream.Close();
}
public static void zip(string strFile, ZipOutputStream outstream, string staticFile)
{
if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar)
{
strFile += Path.DirectorySeparatorChar;
}
var crc = new Crc32();
//获取指定目录下所有文件和子目录文件名称
string[] filenames = Directory.GetFileSystemEntries(strFile);
zip(filenames, outstream, staticFile);
}
public static void zipFiles(string[] filenames, string parentDirectory, out byte[] buffer)
{
var stream = new MemoryStream();
var outstream = new ZipOutputStream(stream);
outstream.SetLevel(6);
zip(filenames, outstream, parentDirectory);
outstream.Finish();
stream.Seek(0, SeekOrigin.Begin);
buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
outstream.Close();
}
///
/// 压缩多个文件
///
/// 要进行压缩的文件集合
/// 压缩目标文件
public static void ZipFilesWithLevel(List sourceFiles, string targetZipFile, int compressionLevel)
{
foreach (var fileToZip in sourceFiles)
{
//如果文件没有找到,则报错
if (!File.Exists(fileToZip))
{
throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!");
}
}
using var ZipFile = File.Create(targetZipFile);
using var ZipStream = new ZipOutputStream(ZipFile);
foreach (var fileToZip in sourceFiles)
{
var fileName = fileToZip.Substring(fileToZip.LastIndexOf(Path.DirectorySeparatorChar));
using var fs = File.OpenRead(fileToZip);
var buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
var ZipEntry = new ZipEntry(fileName);
ZipStream.PutNextEntry(ZipEntry);
ZipStream.SetLevel(compressionLevel);
ZipStream.Write(buffer, 0, buffer.Length);
}
ZipStream.Finish();
ZipStream.Close();
}
private static void zip(string[] filenames, ZipOutputStream outstream, string staticFile)
{
var crc = new Crc32();
//遍历文件
foreach (var file in filenames)
{
if (Directory.Exists(file))
{
zip(file, outstream, staticFile);
}
//否则,直接压缩文件
else
{
//打开文件
var fs = File.OpenRead(file);
//定义缓存区对象
var buffer = new byte[fs.Length];
//通过字符流,读取文件
fs.Read(buffer, 0, buffer.Length);
//得到目录下的文件(比如:D:\Debug1\test),test
//这里是为了得到压缩文件内的目录结构;
string tempfile = file.Substring(staticFile.LastIndexOf(Path.DirectorySeparatorChar) + 1);
//string tempfile = Path.GetFileName(file);
ZipEntry entry = new ZipEntry(tempfile)
{
DateTime = DateTime.Now,
Size = fs.Length
};
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
outstream.PutNextEntry(entry);
//写文件
outstream.Write(buffer, 0, buffer.Length);
}
}
}
public static string unZipFile(string TargetFile, string fileDir, out string msg)
{
LogFactory.GetLogger("UploadEventReportFile").Info($"准备解压{fileDir}->{TargetFile}");
msg = "";
//读取压缩文件(zip文件),准备解压缩
using (var inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim())))
{
ZipEntry entry;
var pathName = Path.GetFileNameWithoutExtension(TargetFile);
fileDir = Path.Combine(fileDir, pathName);
LogFactory.GetLogger("UploadEventReportFile").Info($"准备解压{fileDir}");
var path = fileDir;
//压缩文件内第一层子目录
var rootDir = "";
//压缩文件内子目录
var dir = "";
var fileName = "";
while ((entry = inputstream.GetNextEntry()) != null)
{
if (!string.IsNullOrWhiteSpace(entry.Name))
{
//得到根目录下的第一级子文件夹的名称
rootDir = Path.GetDirectoryName(entry.Name);
if (rootDir.IndexOf(Path.DirectorySeparatorChar) >= 0)
{
rootDir = rootDir.Substring(0, rootDir.IndexOf(Path.DirectorySeparatorChar) + 1);
}
//得到根目录下的第一级子文件夹下的子文件夹名称
dir = Path.GetDirectoryName(entry.Name);
//根目录下的文件名称
fileName = Path.GetFileName(entry.Name);
}
LogFactory.GetLogger("UploadEventReportFile").Info($"根目录下的文件名称{fileName}");
//创建根目录下的子文件夹,不限制级别
if (!Directory.Exists(fileDir + Path.DirectorySeparatorChar + dir))
{
path = fileDir + Path.DirectorySeparatorChar + dir;
//在指定的路径创建文件夹
Directory.CreateDirectory(path);
LogFactory.GetLogger("UploadEventReportFile").Info($"在指定的路径创建文件夹{path}");
}
if (dir == "" && fileName != "")
{
//根目录下的文件
path = fileDir;
}
else if (dir != "" && fileName != "")
{
//根目录下的第一级子文件夹下的文件
if (dir.IndexOf(Path.DirectorySeparatorChar) > 0)
{
//指定文件保存路径
path = fileDir + Path.DirectorySeparatorChar + dir;
LogFactory.GetLogger("UploadEventReportFile").Info($"指定文件保存路径{path}");
}
}
if (dir == rootDir)
{
//判断是不是需要保存在根目录下的文件
path = fileDir + Path.DirectorySeparatorChar + rootDir;
}
//以下为解压zip文件的基本步骤
//基本思路:遍历压缩文件里的所有文件,创建一个相同的文件
if (fileName != string.Empty)
{
var fs = File.Create(path + Path.DirectorySeparatorChar + fileName);
LogFactory.GetLogger("UploadEventReportFile").Info($"遍历压缩文件里的所有文件{fs.Name}");
var size = 2048;
var data = new byte[2048];
while (true)
{
size = inputstream.Read(data, 0, data.Length);
if (size > 0)
{
fs.Write(data, 0, size);
}
else
{
break;
}
}
fs.Close();
}
}
}
msg = "解压成功!";
return fileDir;
}
}
}