C# 壓縮目錄

保存目錄結構

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",因爲"\"是轉義字符;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章