RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2 新增解压缩工具类ZipHelper

简介:

在项目对文件进行解压缩是非常常用的功能,对文件进行压缩存储或传输可以节省流量与空间。压缩文件的格式与方法都比较多,比较常用的国际标准是zip格式。压缩与解压缩的方法也很多,在.NET 2.0开始,在System.IO.Compression中微软已经给我们提供了解压缩的方法GZipStream。对于GZipStream的使用以及优缺点网上已经有非常多的文章,本文主要讲的是利用三方开源组件ICSharpCode.SharpZipLib进行文件的解压缩。

  SharpZipLib地址:http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx

  SharpZipLib是一个使用C#编写的Zip操作类库,是一个开源的C#压缩解压库,应用非常广泛。在VB.NET、C#或其他的.NET语言中都可以使用它创建Zip文件、并进行读取和更新等操作。SharpZipLib是一个完全由c#编写的Zip, GZip, Tar and BZip2 library,可以方便地支持这几种格式的压缩解压缩。SharpZipLib目前的版本为0.86,我们可以直接从上面提供的网站下载dll文件再添加到项目引用中,也可以通过VS提供的包管理工具NuGet把SharpZipLib添加到项目中。NuGet能更方便地把一些dll和文件添加到项目中,而不需要从文件中复制拷贝,推荐使用。使用NuGet添加SharpZipLib到项目中的方法如下图所示,在我们需要SharpZipLib的项目中右键单击“引用”,在弹出的快捷菜单中选择“管理NuGet程序包(N)…”。

 

  在打开的“管理NuGet程序包”对话框,搜索SharpZipLib找到后单击安装即可。

  引用SharpZipLib到项目中后,我们就可以编写相应的加压缩方法,下面将对常用的方法一一分享。

  在使用前必须先添加引用如下:

1
2
using  ICSharpCode.SharpZipLib.Checksums;
using  ICSharpCode.SharpZipLib.Zip;  

  一、压缩文件夹 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/// <summary>
    /// 压缩文件夹
    /// </summary>
    /// <param name="dirToZip"></param>
    /// <param name="zipedFileName"></param>
    /// <param name="compressionLevel">压缩率0(无压缩)9(压缩率最高)</param>
    public  static  void  ZipDir( string  dirToZip,  string  zipedFileName,  int  compressionLevel = 9)
    {
        if  (Path.GetExtension(zipedFileName) !=  ".zip" )
        {
            zipedFileName = zipedFileName +  ".zip" ;
        }
        using  ( var  zipoutputstream =  new  ZipOutputStream(File.Create(zipedFileName)))
        {
            zipoutputstream.SetLevel(compressionLevel);
            Crc32 crc =  new  Crc32();
            Hashtable fileList = GetAllFies(dirToZip);
            foreach  (DictionaryEntry item  in  fileList)
            {
                FileStream fs =  new  FileStream(item.Key.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                byte [] buffer =  new  byte [fs.Length];
                fs.Read(buffer, 0, buffer.Length);;
                ZipEntry entry =  new  ZipEntry(Path.GetFileName(item.Key.ToString()))
                {
                    DateTime = (DateTime)item.Value,
                    Size = fs.Length
                };
                fs.Close();
                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;
                zipoutputstream.PutNextEntry(entry);
                zipoutputstream.Write(buffer, 0, buffer.Length);
            }
        }
    }

  二、解压文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/// <summary> 
    /// 功能:解压zip格式的文件。 
    /// </summary> 
    /// <param name="zipFilePath">压缩文件路径</param> 
    /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param> 
    /// <returns>解压是否成功</returns> 
    public  static  void  UnZip( string  zipFilePath,  string  unZipDir)
    {
        if  (zipFilePath ==  string .Empty)
        {
            throw  new  Exception( "压缩文件不能为空!" );
        }
        if  (!File.Exists(zipFilePath))
        {
            throw  new  FileNotFoundException( "压缩文件不存在!" );
        }
        //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹 
        if  (unZipDir ==  string .Empty)
            unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
        if  (!unZipDir.EndsWith( "/" ))
            unZipDir +=  "/" ;
        if  (!Directory.Exists(unZipDir))
            Directory.CreateDirectory(unZipDir);
 
        using  ( var  s =  new  ZipInputStream(File.OpenRead(zipFilePath)))
        {
 
            ZipEntry theEntry;
            while  ((theEntry = s.GetNextEntry()) !=  null )
            {
                string  directoryName = Path.GetDirectoryName(theEntry.Name);
                string  fileName = Path.GetFileName(theEntry.Name);
                if  (! string .IsNullOrEmpty(directoryName))
                {
                    Directory.CreateDirectory(unZipDir + directoryName);
                }
                if  (directoryName !=  null  && !directoryName.EndsWith( "/" ))
                {
                }
                if  (fileName != String.Empty)
                {
                    using  (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
                    {
 
                        int  size;
                        byte [] data =  new  byte [2048];
                        while  ( true )
                        {
                            size = s.Read(data, 0, data.Length);
                            if  (size > 0)
                            {
                                streamWriter.Write(data, 0, size);
                            }
                            else
                            {
                                break ;
                            }
                        }
                    }
                }
            }
        }
    }

  三、压缩单个文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/// <summary>
   /// 压缩单个文件
   /// </summary>
   /// <param name="fileToZip">要进行压缩的文件名,全路径</param>
   /// <param name="zipedFile">压缩后生成的压缩文件名,全路径</param>
   public  static  void  ZipFile( string  fileToZip,  string  zipedFile)
   {
       // 如果文件没有找到,则报错
       if  (!File.Exists(fileToZip))
       {
           throw  new  FileNotFoundException( "指定要压缩的文件: "  + fileToZip +  " 不存在!" );
       }
       using  (FileStream fileStream = File.OpenRead(fileToZip))
       {
           byte [] buffer =  new  byte [fileStream.Length];
           fileStream.Read(buffer, 0, buffer.Length);
           fileStream.Close();
           using  (FileStream zipFile = File.Create(zipedFile))
           {
               using  (ZipOutputStream zipOutputStream =  new  ZipOutputStream(zipFile))
               {
                   // string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
                   string  fileName = Path.GetFileName(fileToZip);
                   var  zipEntry =  new  ZipEntry(fileName)
                   {
                       DateTime = DateTime.Now,
                       IsUnicodeText =  true
                   };
                   zipOutputStream.PutNextEntry(zipEntry);
                   zipOutputStream.SetLevel(5);
                   zipOutputStream.Write(buffer, 0, buffer.Length);
                   zipOutputStream.Finish();
                   zipOutputStream.Close();
               }
           }
       }
   }

  三、压缩单个文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
    /// 压缩多个目录或文件
    /// </summary>
    /// <param name="folderOrFileList">待压缩的文件夹或者文件,全路径格式,是一个集合</param>
    /// <param name="zipedFile">压缩后的文件名,全路径格式</param>
    /// <param name="password">压宿密码</param>
    /// <returns></returns>
    public  static  bool  ZipManyFilesOrDictorys(IEnumerable< string > folderOrFileList,  string  zipedFile,  string  password)
    {
        bool  res =  true ;
        using  ( var  s =  new  ZipOutputStream(File.Create(zipedFile)))
        {
            s.SetLevel(6);
            if  (! string .IsNullOrEmpty(password))
            {
                s.Password = password;
            }
            foreach  ( string  fileOrDir  in  folderOrFileList)
            {
                //是文件夹
                if  (Directory.Exists(fileOrDir))
                {
                    res = ZipFileDictory(fileOrDir, s,  "" );
                }
                else
                {
                    //文件
                    res = ZipFileWithStream(fileOrDir, s);
                }
            }
            s.Finish();
            s.Close();
            return  res;
        }
    }

  五、递归压缩文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/// <summary>
    /// 递归压缩文件夹方法
    /// </summary>
    /// <param name="folderToZip"></param>
    /// <param name="s"></param>
    /// <param name="parentFolderName"></param>
    private  static  bool  ZipFileDictory( string  folderToZip, ZipOutputStream s,  string  parentFolderName)
    {
        bool  res =  true ;
        ZipEntry entry =  null ;
        FileStream fs =  null ;
        Crc32 crc =  new  Crc32();
        try
        {
            //创建当前文件夹
            entry =  new  ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) +  "/" ));  //加上 “/” 才会当成是文件夹创建
            s.PutNextEntry(entry);
            s.Flush();
            //先压缩文件,再递归压缩文件夹
            var  filenames = Directory.GetFiles(folderToZip);
            foreach  ( string  file  in  filenames)
            {
                //打开压缩文件
                fs = File.OpenRead(file);
                byte [] buffer =  new  byte [fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                entry =  new  ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) +  "/"  + Path.GetFileName(file)));
                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);
            }
        }
        catch
        {
            res =  false ;
        }
        finally
        {
            if  (fs !=  null )
            {
                fs.Close();
            }
            if  (entry !=  null )
            {
            }
            GC.Collect();
            GC.Collect(1);
        }
        var  folders = Directory.GetDirectories(folderToZip);
        foreach  ( string  folder  in  folders)
        {
            if  (!ZipFileDictory(folder, s, Path.Combine(parentFolderName, Path.GetFileName(folderToZip))))
            {
                return  false ;
            }
        }
        return  res;
    }

  利用ICSharpCode.SharpZipLib解压缩辅助类全部代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30