Post

C# ZipArchive

ZipArchive

C# ZipArchive

Git Source


ZipArchive 🐔

  • 참조
    • System.IO.Compression
    • System.IO.Compression.FileSystem

.Net Framework 4.5 부터 압축에 대한 라이브러리가 제공이 되며 이번 포스트에서는 제공되는 라이브러리 중 ZipArchive를 사용한다.

  • 압축하기
    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
    
    internal static void CreateZip(string contentsFolderPath, string saveZipPath, string extention = "*")
    {
      if (!Directory.Exists(contentsFolderPath))
          throw new DirectoryNotFoundException($"The directory is not found. \n{contentsFolderPath}");
    
      if (!Directory.Exists(saveZipPath))
          Directory.CreateDirectory(Path.GetDirectoryName(saveZipPath));
    
      using (var fs = new FileStream(saveZipPath, FileMode.Create, FileAccess.ReadWrite))
      using (var za = new ZipArchive(fs, ZipArchiveMode.Create))
      {
          foreach (var filePath in Directory.EnumerateFiles(contentsFolderPath, $"*.{extention}", SearchOption.AllDirectories))
          {
              try
              { 
                  za.CreateEntryFromFile(filePath, Path.GetFileName(filePath));
                                        
                  //var entry = za.CreateEntry(Path.GetFileName(filePath));
                  //using (var es = entry.Open())
                  //using (var writer = new StreamWriter(es))
                  //{
                  //    writer.Write(File.ReadAllText(filePath));
                  //}
              }
              catch
              {
                  throw;
              }
          }
      }
    }
    
    • ZipArchive 클래스의 확장세머드인 CreateEntryFromFile 정의
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      
        // 요약:
        //     압축 zip 보관 파일에 추가 하 여 파일에 보관 합니다.
        //
        // 매개 변수:
        //   destination:
        //     Zip 보관 파일을 추가 합니다.
        //
        //   sourceFileName:
        //     보관 파일에 대 한 경로입니다. 상대 경로 또는 절대 경로를 지정할 수 있습니다. 상대 경로는 현재 작업 디렉터리에 상대적으로 해석됩니다.
        //
        //   entryName:
        //     Zip 보관 파일에서 만들 항목의 이름입니다.
        //
        // 반환 값:
        //     Zip 보관 파일에서 새 항목에 대 한 래퍼.
        // 
        public static ZipArchiveEntry CreateEntryFromFile(this ZipArchive destination, string sourceFileName, string entryName);
      
    • sourceFileName의 contents를 가져와 entryName의 이름으로 ZipArchive entry에 추가하는 것 같다. (주석 구문과 동일한 기능인 듯 하다.)
    • 주석구문에 ZipArchive 클래스의 인스턴스 메서드인 CreateEntry를 사용하게되면 항목의 entry가 생성되므로 해당 entry의 stream을 가져와 주석구문처럼 write 해주어야한다. (추가적인 write 없이 해당 파일의 contents만 가져오는 경우면 CreateEntryFromFile를 사용하면 될 것 같다.)
  • 압축 해제하기
    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
    
    internal static void ExtractZip(string zipPath, string extractFolderPath)
    {
      if (!File.Exists(zipPath))
          throw new FileNotFoundException($"The file is not found. \n{zipPath}");
    
      if (!Directory.Exists(extractFolderPath))
          Directory.CreateDirectory(Path.GetDirectoryName(extractFolderPath));
    
      using (var zipArchive = ZipFile.OpenRead(zipPath))
      {
          foreach (var zipArchiveEntry in zipArchive.Entries)
          {
              try
              {
                  string folderPath = Path.GetDirectoryName(Path.Combine(extractFolderPath, zipArchiveEntry.FullName));
    
                  if (!Directory.Exists(folderPath))
                      Directory.CreateDirectory(folderPath);
    
                  zipArchiveEntry.ExtractToFile(Path.Combine(extractFolderPath, zipArchiveEntry.FullName));
              }
              catch
              {
                  throw;
              }
          }
      }
    }
    
    • 압축 해제는 간단하게 zip파일의 경로를 ZipArchive로 읽어들여서 안에 있는 항목(entry)를 순환하며 확장메서드인 ExtractToFile를 이용하여 지정경로에 파일을 쓴다.
  • 사용
    1
    2
    3
    4
    5
    6
    7
    8
    
    static void Main(string[] args)
    {
      var contentsPath = @"Sample";
      var zipPath = Path.Combine(contentsPath, "sample.zip");
    
      Zip.CreateZip(contentsPath, zipPath, "txt");
      Zip.ExtractZip(zipPath, Path.Combine(contentsPath, "zipFolder"));
    } 
    
  • 샘플 sample

  • 결과 result

Reference

ZipArchive Class

This post is licensed under CC BY 4.0 by the author.