保存目錄結構
ZipHelper幫助類
public class ZipHelper
{
public static readonly FastZip Instance = new FastZip() {
EntryFactory = new ZipEntryFactory() {
//UTF8,否則中文文件打包亂碼
IsUnicodeText = true
}
};
/// <summary>
/// 自動包含子目錄,壓縮文件夾 window 資源管理不能直接打開
/// </summary>
/// <param name="dirToZip"></param>
/// <param name="baseStream"></param>
/// <param name="compressionLevel">壓縮率0(無壓縮)9(壓縮率最高)</param>
public static void ZipDir(string dirToZip, Stream baseStream,
string searchPattern = null,
SearchOption option = SearchOption.TopDirectoryOnly,
int compressionLevel = 9)
{
const int BLOCK_SIZE = 1024;
if (!Directory.Exists(dirToZip))
{
throw new FileNotFoundException(dirToZip);
}
if (!(dirToZip.EndsWith("\\") || dirToZip.EndsWith("/")))
{
dirToZip += Path.DirectorySeparatorChar;
}
dirToZip = dirToZip.Replace("\\\\", "/").Replace("//", "/");
string[] files = null;
if (!string.IsNullOrEmpty(searchPattern))
{
files = Directory.GetFileSystemEntries(dirToZip, searchPattern, option);
}
else
{
files = Directory.GetFileSystemEntries(dirToZip);
}
int index = dirToZip.Length;
ZipOutputStream zipoutputstream = new ZipOutputStream(baseStream);
zipoutputstream.SetLevel(compressionLevel);
byte[] buffer = new byte[BLOCK_SIZE];
//目錄分隔符是"/",而不是"\"
foreach (string file in files)
{
ZipEntry entry = null;
if (Directory.Exists(file))
{
entry = new ZipEntry(file.Substring(index) + "/")
{
DateTime = Directory.GetLastWriteTime(file)
};
zipoutputstream.PutNextEntry(entry);
continue;
}
using (FileStream fs = File.OpenRead(file))
{
entry = new ZipEntry(file.Substring(index))
{
DateTime = File.GetLastWriteTime(file),
Size = fs.Length//很重要,否則空文件打包不進去
};
zipoutputstream.PutNextEntry(entry);
int count = fs.Read(buffer, 0, BLOCK_SIZE);
while (count > 0)
{
zipoutputstream.Write(buffer, 0, count);
count = fs.Read(buffer, 0, BLOCK_SIZE);
}
}
}
}
}
測試後發現,用windows資源管理器打不開報錯,所以直接使用FastZip方法可以直接打開
using(FileStream fs = File.Create(@"E:\download\1.zip"))
{
//FileFilter和DirectoryFilter是正則表達式 匹配以“1_”開頭的文件
ZipHelper.Instance.CreateZip(fs,@"E:\upload\product",true,"\\\\1_[^\\]+\\.\\w+",null);
}
注意,FastZip使用的PathFilter,過濾使用正則,windows系統路徑分隔符"\"加上一個數字的正則,是不合法的,因爲他表示分組求值,而應該要轉義一下,寫爲"\\1",在C#字符串中應該寫爲"\\\\1",因爲"\"是轉義字符;