压缩:
/// <summary>
/// 压缩文件
/// </summary>
public class ZipFile
{
public ZipFile()
{
}
/// <summary>
/// 获取文件压缩进度
/// </summary>
/// <param name="CurrentZipFileLength">当前文件压缩的流长</param>
/// <param name="length">当前压缩文件的总长度</param>
public delegate void GetZipFileProgress(int CurrentZipFileLength,long length);
/// <summary>
/// 获取文件压缩进度事件
/// </summary>
public event GetZipFileProgress GetZipFileProgressEvent;
/// <summary>
/// 获取文件夹压缩进度
/// </summary>
/// <param name="count">当前压缩有几个文件</param>
/// <param name="counts">当前问价有几个文件</param>
public delegate void GetZipFolderProgress(int count, int counts);
/// <summary>
/// 获取文件夹压缩进度事件
/// </summary>
public event GetZipFolderProgress GetZipFolderProgressEvent;
/// <summary>
/// 压缩单个文件
/// </summary>
/// <param name="FileToZip">需要压缩的源文件路径及名称</param>
/// <param name="ZipedFile">压缩后的文件名</param>
/// <param name="CompressionLevel">压缩等级(0-9)</param>
/// <param name="BlockSize">每次压缩的大小</param>
/// <returns></returns>
public bool Zip(string FileToZip, string ZipedFile, int CompressionLevel, int BlockSize)
{
//如果文件没有找到,则报错
System.Diagnostics.Debug.Assert(File.Exists(FileToZip), "该文件不存在");
//if (!System.IO.File.Exists(FileToZip))
//{
// //文件不存在
// //return;
//
// //throw new System.IO.FileNotFoundException("文件不存在 " + FileToZip + " could not be found. Zipping aborderd");
//}
bool result = true;
//获取源文件名
int index = FileToZip.LastIndexOf('\\')+1;
//打开源文件并读取它
FileStream StreamToZip = new FileStream(FileToZip, FileMode.Open, FileAccess.Read);
//获取源文件长度
long length = StreamToZip.Length;
FileStream ZipFile = File.Create(ZipedFile);
ZipOutputStream ZipStream = new ZipOutputStream(ZipFile);
ZipEntry ZipEntry = new ZipEntry(FileToZip.Substring(index));
ZipStream.PutNextEntry(ZipEntry);
//压缩等级
ZipStream.SetLevel(CompressionLevel);
byte[] buffer = new byte[BlockSize];
Int32 size = StreamToZip.Read(buffer, 0, buffer.Length);
ZipStream.Write(buffer, 0, size);
try
{
while (size < StreamToZip.Length)
{
int sizeRead = StreamToZip.Read(buffer, 0, buffer.Length);
ZipStream.Write(buffer, 0, sizeRead);
size += sizeRead;
if(GetZipFileProgressEvent!=null)
{
GetZipFileProgressEvent(size, length);
}
}
}
catch (Exception ex)
{
Logger.Trace(ex);
result = false;
}
finally
{
if (ZipStream!=null)
{
ZipStream.Finish();
ZipStream.Close();
}
if (StreamToZip!=null)
{
StreamToZip.Close();
}
}
return result;
}
/// <summary>
/// 压缩文件夹(直接压缩),返回是否成功
/// </summary>
/// <param name="sRootDir"></param>
/// <param name="zipFileName"></param>
/// <returns></returns>
public bool ZipDir(string sRootDir, string zipFileName)
{
return ZipFileMain(new string[] { sRootDir, zipFileName });
}
/// <summary>
/// 获取压缩文件夹中文件是否成功的信息
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
private bool ZipFileMain(string[] args)
{
string[] filenames = Directory.GetFiles(args[0]);
//获取文件夹有几个文件
int counts = filenames.Length;
int count = 0;
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
bool result = true;
try
{
s.SetLevel(6); // 0 - store only to 9 - means best compression
foreach (string file in filenames)
{
//打开压缩文件
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file.Replace(args[0], ""));
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);
count++;
if (GetZipFolderProgressEvent != null)
{
GetZipFolderProgressEvent(count, counts);
}
}
string[] dirs = Directory.GetDirectories(args[0]);
foreach (string dir in dirs)
{
//if (dir.IndexOf("tempdoc") > 0) continue;
ZipDir(args[0], dir, s, crc);
}
}
catch (Exception ex)
{
Logger.Trace(ex);
return false;
}
finally
{
if (s != null)
{
s.Finish();
s.Close();
}
}
return result;
}
/// <summary>
/// 文件夹压缩
/// </summary>
/// <param name="sRootDir"></param>
/// <param name="sDir"></param>
/// <param name="s"></param>
/// <param name="crc"></param>
private void ZipDir(string sRootDir, string sDir, ZipOutputStream s, Crc32 crc)
{
string[] filenames = Directory.GetFiles(sDir);
string[] dirs = Directory.GetDirectories(sDir);
foreach (string file in filenames)
{
//打开压缩文件
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file.Replace(sRootDir, ""));
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);
}
foreach (string dir in dirs)
{
//if (dir.IndexOf("tempdoc") > 0) continue;
ZipDir(sRootDir, dir, s, crc);
}
}
/// <summary>
/// 获取压缩文件夹中部分文件
/// </summary>
/// <param name="args"></param>
/// <param name="files">文件夹中不需要压缩文件的名称</param>
/// <returns></returns>
public bool ZipFolderContainFile(string[] args,string[] files)
{
string[] filenames = Directory.GetFiles(args[0]);
//获取文件夹有几个文件是要压缩的
int counts = filenames.Length-files.Length;
int count = 0;
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(args[1]));
bool result = true;
try
{
s.SetLevel(6); // 0 - store only to 9 - means best compression
foreach (string file in filenames)
{
foreach(string filename in files)
{
if(file==filename)
{
break;
}
//打开压缩文件
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(file.Replace(args[0], ""));
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);
count++;
if (GetZipFolderProgressEvent != null)
{
GetZipFolderProgressEvent(count, counts);
}
}
}
string[] dirs = Directory.GetDirectories(args[0]);
foreach (string dir in dirs)
{
//if (dir.IndexOf("tempdoc") > 0) continue;
ZipDir(args[0], dir, s, crc);
}
}
catch (Exception ex)
{
Logger.Trace(ex);
result = false;
}
finally
{
if (s != null)
{
s.Finish();
s.Close();
}
}
return result;
}
/// <summary>
/// 压缩文件列表
/// </summary>
/// <param name="fileNameList">要压缩的文件列表</param>
/// <param name="zipFileName">压缩后的生成文件</param>
/// <returns>true表示压缩成功,false表示压缩失败</returns>
public bool ZipFiles(List<string> fileNameList,string zipFileName)
{
string[] filenames = fileNameList.ToArray();
//获取文件夹有几个文件
int counts = filenames.Length;
int count = 0;
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(zipFileName));
bool result = true;
try
{
s.SetLevel(6); // 0 - store only to 9 - means best compression
foreach (string file in filenames)
{
//打开压缩文件
FileStream fs = File.OpenRead(file);
long pai = 1024 * 1024 * 1;//每1兆写一次
long forint = fs.Length / pai + 1;
byte[] buffer = null;
string replacePath = Path.GetDirectoryName(file);
string filename = file.Replace(replacePath + "\\", "");//只是获取文件名,但是没有目录
ZipEntry entry = new ZipEntry(filename);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
s.PutNextEntry(entry);
//分段压缩
for (long i = 1; i <= forint; i++)
{
if (pai * i < fs.Length)
{
buffer = new byte[pai];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
else
{
if (fs.Length < pai)
{
buffer = new byte[fs.Length];
}
else
{
buffer = new byte[fs.Length - pai * (i - 1)];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
}
fs.Read(buffer, 0, buffer.Length);
crc.Reset();
crc.Update(buffer);
s.Write(buffer, 0, buffer.Length);
s.Flush();
}
fs.Close();
count++;
if (GetZipFolderProgressEvent != null)
{
GetZipFolderProgressEvent(count, counts);
}
}
}
catch (Exception ex)
{
Logger.Trace(ex);
result= false;
}
finally
{
if (s != null)
{
s.Finish();
s.Close();
}
}
return result;
}
/// <summary>
/// 压缩多层目录(压缩文件夹采用分阶段压缩)
/// </summary>
/// <param name="strDirectory">要压缩的目录</param>
/// <param name="zipedFile">压缩后的生成文件</param>
/// <returns>true表示压缩成功,false表示压缩失败</returns>
public static bool ZipFileDirectory(string strDirectory, string zipedFile)
{
//要压缩的目录不存在
if (!Directory.Exists(strDirectory))
{
return false;
}
bool zipIsSuccess;
using (FileStream zipFile = System.IO.File.Create(zipedFile))
{
using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
{
zipIsSuccess = ZipSetp(strDirectory, zipOutputStream, "", zipedFile);
}
}
return zipIsSuccess;
}
/// <summary>
/// 压缩多层目录(压缩文件夹采用分阶段压缩)
/// </summary>
/// <param name="strDirectory">要压缩的目录</param>
/// <param name="zipedFile">压缩后的生成文件</param>
/// <returns>true表示压缩成功,false表示压缩失败</returns>
public static bool ZipFileDirectory(string strDirectory, string zipedFile, List<string> withoutDirectorys)
{
//要压缩的目录不存在
if (!Directory.Exists(strDirectory))
{
return false;
}
bool zipIsSuccess;
using (FileStream zipFile = System.IO.File.Create(zipedFile))
{
using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
{
zipIsSuccess = ZipSetp(strDirectory, zipOutputStream, "", withoutDirectorys, zipedFile);
}
}
return zipIsSuccess;
}
/// <summary>
/// 递归遍历目录
/// </summary>
/// <param name="strDirectory">要压缩的目录</param>
/// <param name="zipOutputStream">压缩后的生成文件流</param>
/// <param name="parentPath">当前父目录</param>
/// <returns>true表示压缩成功,false表示压缩失败</returns>
private static bool ZipSetp(string strDirectory, ZipOutputStream zipOutputStream, string parentPath, string targetZipPath)
{
if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
{
strDirectory += Path.DirectorySeparatorChar;
}
try
{
Crc32 crc = new Crc32();
string[] filenames = Directory.GetFileSystemEntries(strDirectory);
foreach (string file in filenames)// 遍历所有的文件和目录
{
if (Directory.Exists(file))// 当是目录时,就递归该目录下面的文件
{
string pPath = parentPath;
pPath += file.Substring(file.LastIndexOf("\\") + 1);
pPath += "\\";
ZipSetp(file, zipOutputStream, pPath, targetZipPath);
}
else // 否则直接压缩文件
{
if (file != targetZipPath)
{
using (FileStream fs = File.OpenRead(file))
{
//分段压缩,主要解决单个文件太大
long pai = 1024 * 1024 * 1;//每1兆写一次
long forint = fs.Length / pai + 1;
byte[] buffer = null;
string filename = parentPath + file.Substring(file.LastIndexOf("\\") + 1);//获取文件名,但有目录
ZipEntry entry = new ZipEntry(filename);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
zipOutputStream.PutNextEntry(entry);
for (long i = 1; i <= forint; i++)
{
if (pai * i < fs.Length)
{
buffer = new byte[pai];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
else
{
if (fs.Length < pai)
{
buffer = new byte[fs.Length];
}
else
{
buffer = new byte[fs.Length - pai * (i - 1)];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
}
fs.Read(buffer, 0, buffer.Length);
crc.Reset();
crc.Update(buffer);
zipOutputStream.Write(buffer, 0, buffer.Length);
zipOutputStream.Flush();
}
//直接压缩
//byte[] buffer = new byte[fs.Length];
//fs.Read(buffer, 0, buffer.Length);
//string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
//ZipEntry entry = new ZipEntry(fileName);
//entry.DateTime = DateTime.Now;
//entry.Size = fs.Length;
//fs.Close();
//crc.Reset();
//crc.Update(buffer);
//entry.Crc = crc.Value;
//zipOutputStream.PutNextEntry(entry);
//zipOutputStream.Write(buffer, 0, buffer.Length);
}
}
}
}
}
catch (Exception exception)
{
zipOutputStream.Flush();
zipOutputStream.Close();
return false;
}
return true;
}
/// <summary>
/// 递归遍历目录
/// </summary>
/// <param name="strDirectory">要压缩的目录</param>
/// <param name="zipOutputStream">压缩后的生成文件流</param>
/// <param name="parentPath">当前父目录</param>
/// <returns>true表示压缩成功,false表示压缩失败</returns>
private static bool ZipSetp(string strDirectory, ZipOutputStream zipOutputStream, string parentPath, List<string> withoutDirectorys, string targetZipPath)
{
if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar)
{
strDirectory += Path.DirectorySeparatorChar;
}
try
{
Crc32 crc = new Crc32();
string[] filenames = Directory.GetFileSystemEntries(strDirectory);
foreach (string file in filenames)// 遍历所有的文件和目录
{
if (Directory.Exists(file))// 当是目录时,就递归该目录下面的文件
{
if (withoutDirectorys.Contains(file))
continue;
string pPath = parentPath;
pPath += file.Substring(file.LastIndexOf("\\") + 1);
pPath += "\\";
ZipSetp(file, zipOutputStream, pPath, targetZipPath);
}
else // 否则直接压缩文件
{
using (FileStream fs = File.OpenRead(file))
{
//分段压缩,主要解决单个文件太大
long pai = 1024 * 1024 * 1;//每1兆写一次
long forint = fs.Length / pai + 1;
byte[] buffer = null;
string filename = parentPath + file.Substring(file.LastIndexOf("\\") + 1);//获取文件名,但有目录
ZipEntry entry = new ZipEntry(filename);
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
zipOutputStream.PutNextEntry(entry);
for (long i = 1; i <= forint; i++)
{
if (pai * i < fs.Length)
{
buffer = new byte[pai];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
else
{
if (fs.Length < pai)
{
buffer = new byte[fs.Length];
}
else
{
buffer = new byte[fs.Length - pai * (i - 1)];
fs.Seek(pai * (i - 1), System.IO.SeekOrigin.Begin);
}
}
fs.Read(buffer, 0, buffer.Length);
crc.Reset();
crc.Update(buffer);
zipOutputStream.Write(buffer, 0, buffer.Length);
zipOutputStream.Flush();
}
//直接压缩
//byte[] buffer = new byte[fs.Length];
//fs.Read(buffer, 0, buffer.Length);
//string fileName = parentPath + file.Substring(file.LastIndexOf("\\") + 1);
//ZipEntry entry = new ZipEntry(fileName);
//entry.DateTime = DateTime.Now;
//entry.Size = fs.Length;
//fs.Close();
//crc.Reset();
//crc.Update(buffer);
//entry.Crc = crc.Value;
//zipOutputStream.PutNextEntry(entry);
//zipOutputStream.Write(buffer, 0, buffer.Length);
}
}
}
}
catch (Exception exception)
{
return false;
}
return true;
}
/// <summary>
/// 更新 Zip 包中的文件
/// </summary>
/// <param name="srcZipFileName">Zip 包的全名</param>
/// <param name="srcFileName">要添加到包中的文件名</param>
/// <param name="destPath">文件在Zip包中的相对位置</param>
public void UpdateZipFile(String srcZipFileName, String srcFileName, String destPath)
{
string[] unZipFileInfos = new string[2];
unZipFileInfos[0] = srcZipFileName;
//获取临时解压目录
string tempDirectory = Path.GetDirectoryName(srcZipFileName) + Path.DirectorySeparatorChar + System.Guid.NewGuid().ToString().Replace("-", "") + Path.DirectorySeparatorChar;
//要更新的文件在临时文件夹中位置
string destFilePath=tempDirectory+destPath;
unZipFileInfos[1] = tempDirectory;
//如果临时文件夹目录不存在则创建
if (!System.IO.Directory.Exists(tempDirectory))
{
System.IO.Directory.CreateDirectory(tempDirectory);
}
CommonLibrary.UnZipFile unZipFile = new UnZipFile();
//解压文件到临时文件夹
unZipFile.UnZip(unZipFileInfos);
//更新需要更新的文件
System.IO.File.Copy(srcFileName,destFilePath, true);
//更新完成后重新压缩文件到临时文件夹
ZipFileDirectory(tempDirectory, tempDirectory + Path.GetFileName(srcZipFileName));
//更新zip文件
System.IO.File.Copy(tempDirectory + Path.GetFileName(srcZipFileName), srcZipFileName, true);
//删除临时文件夹
System.IO.Directory.Delete(tempDirectory, true);
//ICSharpCode.SharpZipLib.Zip.ZipFile zipFileEntry = new ICSharpCode.SharpZipLib.Zip.ZipFile(srcZipFileName);
//// Must call BeginUpdate to start, and CommitUpdate at the end.
//zipFileEntry.BeginUpdate();
////添加文件到 Zip 包中
//IStaticDataSource fileEntry = new FileEntry(srcFileName);
//zipFileEntry.Add(fileEntry, destPath);
//// Both CommitUpdate and Close must be called.
//zipFileEntry.CommitUpdate();
//((FileEntry)fileEntry).FileStream.Close();
//zipFileEntry.Close();
}//end method
}//end class
public class FileEntry : IStaticDataSource
{
private FileStream fileStream;
public FileEntry(String filename)
{
fileStream = File.OpenRead(filename);
// fileStream.Close();
}
public Stream GetSource()
{
return fileStream;
}
/// <summary>
/// 对象流
/// </summary>
public FileStream FileStream
{
get { return fileStream; }
}
}//end class