.Net Core 多文件打包壓縮


最近項目需要實現多文件打包的功能,嘗試了一些方法,最后發現使用  ICSharpCode.SharpZipLib 最符合項目的要求。

具體實現如下:

1.在 Nuget 中安裝  ICSharpCode.SharpZipLib

 

 

2.將要打包的文件放到同個文件夾進行壓縮:

①壓縮文件夾

 1         /// <summary>
 2         /// 壓縮文件
 3         /// </summary>        
 4         /// <param name="fileName">壓縮后獲得的文件名</param>  
 5         public static bool CompressFile(string dir, out string fileName)
 6         {
 7             string dest = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + "\\" + string.Format("{0:yyyyMMddHHmmss}", DateTime.Now) + ".zip";   //默認壓縮在桌面上
 8             if (!Directory.Exists(Path.GetDirectoryName(dest)))   //文件不存在就根據路徑創建  E:\\test
 9                 Directory.CreateDirectory(Path.GetDirectoryName(dest));
10             using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(dest)))
11             {
12                 zipStream.SetLevel(6);   //壓縮級別0-9  
13                 CreateZip(dir, zipStream);
14                 fileName = dest;
15                 zipStream.Finish();
16                 zipStream.Close();
17             }
18             return true;
19         }
20         /// <summary>
21         /// 壓縮內容到 zipStream 流中 
22         /// </summary>        
23         /// <param name="source">源文件</param>  
24         /// <param name="zipStream">目標文件流(全路徑+文件名+.zip)</param>
25 
26         private static void CreateZip(string source, ZipOutputStream zipStream)
27         {
28             Crc32 crc = new Crc32();
29             string[] files = Directory.GetFileSystemEntries(source);  //獲得所有文件名稱和目錄名稱
30             foreach (var file in files)
31             {
32                 if (Directory.Exists(file))    //如果是文件夾里有文件則遞歸
33                 {
34                     CreateZip(file, zipStream);
35                 }
36                 else    //如果不是則壓縮
37                 {
38                     using (FileStream fs = File.OpenRead(file))
39                     {
40                         byte[] buffer = new byte[fs.Length];
41                         fs.Read(buffer, 0, buffer.Length);
42                         string tempFileName = file.Substring(file.LastIndexOf("\\") + 1);  //獲得當前文件路徑的文件名
43                         ZipEntry entry = new ZipEntry(tempFileName);
44                         entry.DateTime = DateTime.Now;
45                         entry.Size = fs.Length;
46                         fs.Close();
47                         crc.Reset();
48                         crc.Update(buffer);
49                         entry.Crc = crc.Value;
50                         zipStream.PutNextEntry(entry);
51                         zipStream.Write(buffer, 0, buffer.Length);
52                     }
53                 }
54             }
55         }
View Code

 

②將指定文件打包壓縮 (可打包線上文件)

        /// <summary>
        /// 打包線上線下文件
        /// </summary>
        /// <param name="fileList">文件列表</param>
        /// <param name="savepath">保存路徑</param>
        public static void ZipOnlineFile3(List<string> fileList, string savepath)
        {
            //判斷保存的文件目錄是否存在
            if (!File.Exists(savepath))
            {
                var file = new FileInfo(savepath);
                if (!file.Directory.Exists)
                {
                    file.Directory.Create();
                }
            }

            Crc32 crc = new Crc32();
            using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(savepath)))
            {
                zipStream.SetLevel(9);   //壓縮級別0-9  

                foreach (var url in fileList)
                {
                    byte[] buffer = new WebClient().DownloadData(url);
                    string tempFileName = GetFileNameByUrl(url);  //獲得當前文件路徑的文件名
                    ZipEntry entry = new ZipEntry(tempFileName);
                    entry.DateTime = DateTime.Now;
                    entry.Size = buffer.Length;
                    crc.Reset();
                    crc.Update(buffer);
                    zipStream.PutNextEntry(entry);
                    zipStream.Write(buffer, 0, buffer.Length);
                }
            }
        }
View Code

從文件路徑讀取文件名的方法:

public static string GetFileNameByUrl(string url)
        {
            //判斷路徑是否為空
            if (string.IsNullOrWhiteSpace(url)) return null;

            //判斷是否為線上文件
            if (url.ToLower().StartsWith("http"))
            {
                return url.Substring(url.LastIndexOf("/") + 1);
            }
            else
            {
                return url.Substring(url.LastIndexOf("\\") + 1);
            }
        }
View Code

通過此方法生成的壓縮包,所有文件都會顯示在同一層。

 

③如果需要在文件中創建目錄,需要在文件名稱上指定文件路徑

添加工具類:

 1     /// <summary>
 2     /// 文件對象
 3     /// </summary>
 4     public class FileItem
 5     {
 6         /// <summary>
 7         /// 文件名稱
 8         /// </summary>
 9         public string FileName { get; set; }
10         /// <summary>
11         /// 文件路徑
12         /// </summary>
13         public string FileUrl { get; set; }
14     }
View Code

壓縮文件的方法:

 1         /// <summary>
 2         /// 打包線上線下文件
 3         /// </summary>
 4         /// <param name="zipName">壓縮文件名稱</param>
 5         /// <param name="fileList">文件列表</param>
 6         /// <param name="savepath">保存路徑</param>
 7         public static string ZipFiles(string zipName, List<FileItem> fileList, out string error)
 8         {
 9             error = string.Empty;
10 
11             string path = string.Format("/files/zipFiles/{0}/{1}/{2}/", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
12             //文件保存目錄
13             string directory = FileSavePath + path;
14             string url = FileHostUrl.TrimEnd('/') + path + zipName;
15             string savePath = directory + zipName;
16 
17             try
18             {
19                 if (!Directory.Exists(directory))
20                 {
21                     Directory.CreateDirectory(directory);
22                 }
23 
24                 using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(savePath)))
25                 {
26                     zipStream.SetLevel(9);   //壓縮級別0-9  
27 
28                     foreach (var item in fileList)
29                     {
30                         byte[] buffer = new WebClient().DownloadData(item.FileUrl);
31                         ZipEntry entry = new ZipEntry(item.FileName);
32                         entry.DateTime = DateTime.Now;
33                         entry.Size = buffer.Length;
34                         zipStream.PutNextEntry(entry);
35                         zipStream.Write(buffer, 0, buffer.Length);
36                     }
37                 }
38             }
39             catch (Exception ex)
40             {
41                 error = "文件打包失敗:" + ex.Message;
42             }
43 
44             return url;
45         }
View Code

 

調用參數示例:

{
  "zipName": "test.zip",
  "fileList": [
    {
      "fileName": "123.png",
      "fileUrl": "https://file.yidongcha.cn/files/uploadfiles/image/2021/11/15/11c6de395fcc484faf4745ade62cf6e6.png"
    },
    {
      "fileName": "123/456/789.jpg",
      "fileUrl": "https://file.yidongcha.cn/files/uploadfiles/image/2021/11/15/fe922b250acf4344b8ca4d2aad6e0355.jpg"
    }
  ]
}

生成的結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM