【问题标题】:Adding a directory to an existing .zip file将目录添加到现有 .zip 文件
【发布时间】:2016-07-22 10:21:47
【问题描述】:

首先我想说的是,我已经尝试寻找解决方案,但我还没有找到不需要解压缩、添加文件夹然后再次压缩的解决方案。我没有使用任何第三方库。如果可能的话,我想使用 system.io.compression 来做到这一点......如果没有,我会使用 dotnetzip 作为我最后的手段。

TL;博士。 我希望能够将包含文件的目录添加到已创建的 zip 文件中。这可以使用System.Io.Compression 库吗?

编辑

using (FileStream zipToOpen = new FileStream(zipfile, FileMode.Open))
{
    using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
    {
        ZipArchiveEntry readmeEntry = archive.CreateEntry("testFolder/");
    }
}

因此,使用此代码,我可以在其中创建一个文件夹,但其中没有任何文件。我现在的问题是我是否必须再次运行此代码才能将我的源文件夹中的每个文件都放到 zip 中的这个文件夹中,还是有更好的方法?

【问题讨论】:

  • 明确地说,您是说您只想添加一个文件夹,而不是向其中添加任何文件或将文件移动到其中吗?还是您要添加一个包含文件的目录?
  • 对不起,我没有说清楚,但我想添加一个包含文件的目录。我马上修改
  • How do I add files to an existing zip archive 回答你的问题了吗?
  • 我查看了这个答案,但我不知道如何根据我的需要进行修改(我试过了)。我刚刚想到了其他东西,我可以尝试使用它,我会尽快回复您。
  • @stuartd 我已经用我用来在里面创建文件夹的代码更新了我的问题。

标签: c# compression system.io.compression


【解决方案1】:

感谢@stuartd,我设法找到了一种方法。他向我指出了这个答案https://stackoverflow.com/a/22339337/3182972,我找到了一种将其实现到我的代码中的方法,该方法从所述目录的源位置创建目录,其中包含文件。

代码如下:

   using (FileStream zipToOpen = new FileStream("c:\MyDestination\test.zip", FileMode.Open))
      {
        using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
          {
             ZipArchiveEntry readmeEntry;
             DirectoryInfo d = new DirectoryInfo(c:\MySourceFolder);
             FileInfo[] Files = d.GetFiles("*");
             foreach (FileInfo file in Files)
             {
               readmeEntry = archive.CreateEntryFromFile("c:\MySourceFolder"+ "\\" + file.Name, "MySourceFolder" + "/" + file.Name);
             }
          }
      }

所以我所做的就是转到我的源目录并浏览那里的所有文件,并使用 foreach 循环将它们添加到 zip 文件中的目标文件夹中。

您也可以使用此代码获取源目录名称:

string sourcepath = "C:\MySourceFolder";
int ind = sourcepath.LastIndexOf("\\") + 1;
string folderName = sourcepath.Substring(ind, folder.Length - ind);

【讨论】:

    【解决方案2】:

    这可以这样执行:

    var targetDir = @"D:\test";
    var zipFile = @"D:\test.zip"; 
    using (ZipArchive zipArchive = ZipFile.Open(zipFile, ZipArchiveMode.Read)) 
          zipArchive.AddDirectory(targetDir, "test");
    
    
    
    public static class ExtensionMethods;
        {
    
            public static void AddDirectory(this ZipArchive zip, string targetDir, string subDir = null, CompressionLevel compressionLevel = CompressionLevel.Optimal)
            {
                var ogrDir = targetDir.Replace("/", "\\");
                if (!ogrDir.EndsWith("\\"))
                    ogrDir = ogrDir + "\\";
    
                if (subDir == null)
                    subDir = "";
                else
                {
                    subDir = subDir.Replace("/", "\\");
                    if (subDir.StartsWith("\\"))
                        subDir = subDir.Remove(0, 1);
    
                    if (!subDir.EndsWith("\\"))
                        subDir = subDir + "\\";
                }
                Action<string> AddDirectoryAndSubs = null;
                AddDirectoryAndSubs = delegate (string _targetDir)
                {
                    string[] files = Directory.GetFiles(_targetDir);
                    foreach (string file in files)
                    {
                        var fileInfo = new FileInfo(file);
                        zip.CreateEntryFromFile(fileInfo.FullName, subDir + (fileInfo.Directory.ToString() + "\\").Replace(ogrDir, "") + fileInfo.Name, compressionLevel);
                    }
    
                    string[] dirs = Directory.GetDirectories(_targetDir);
                    foreach (string dir in dirs)
                        AddDirectoryAndSubs(dir);
                };
    
                AddDirectoryAndSubs(targetDir);
            }
    
        }
    

    【讨论】:

    • AddDirectoryAndSubs 可以(在 C# 7.0 中)写为 本地函数 而不是委托,这样可以避免... ...笨拙的代码,其中您首先将 null 分配给委托变量... 它提供了其他改进。见:stackoverflow.com/a/40949214/2115384
    【解决方案3】:

    此代码已准备好在 C# 4.5 + 中使用 System.IO.Copression 引用(并使用子句),它是对先前答案的改进。

        public static void AddDirToZip(string source, string targetzip)
        {
            using (FileStream zipToOpen = new FileStream(targetzip, FileMode.Open))
            {
                using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                {
                    ZipArchiveEntry readmeEntry;
                    DirectoryInfo d = new DirectoryInfo(source);
                    FileInfo[] Files = d.GetFiles("*");
                    foreach (FileInfo file in Files)
                    {
                        readmeEntry = archive.CreateEntryFromFile(file.FullName, d.Name + "/" + file.Name);
                    }
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 2011-01-20
      相关资源
      最近更新 更多