问题
First of all I would like to say that i've tried looking for the solution to this and I haven't found one where I don't have to unzip, add my folder and then zip again. I am not using any third party libraries. I would like to do this using system.io.compression if it's possible at all ... If not I would use dotnetzip as my last resort.
tl;dr. I want to be able to add directories with files in them to an already created zip file. Is this possible using the system.io.compression library ?
EDIT:
using (FileStream zipToOpen = new FileStream(zipfile, FileMode.Open))
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
{
ZipArchiveEntry readmeEntry = archive.CreateEntry("testFolder/");
}
}
So, using this code I am able to create a folder inside but it will be without any files in it. My question now is do I have to run this code again to get every file from my source folder to this folder inside the zip or is there a better way?
回答1:
I managed to find a way to do this thanks to @stuartd. He pointed me to this answer https://stackoverflow.com/a/22339337/3182972 and I found a way to implement it into my code that creates directories with files inside them from a source location of said directories.
Here is the code:
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);
}
}
}
So what I did was go to my source directory and went through all of the files that are there and with a foreach cycle I added them to the destination folder in the zip file.
You can also get the source directory name with this code:
string sourcepath = "C:\MySourceFolder";
int ind = sourcepath.LastIndexOf("\\") + 1;
string folderName = sourcepath.Substring(ind, folder.Length - ind);
回答2:
This can be performed this way:
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);
}
}
回答3:
This code is ready to go in C# 4.5 + with System.IO.Copression referenced (and having it in using clausules), it is improvement of previous answer.
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);
}
}
}
}
来源:https://stackoverflow.com/questions/38524005/adding-a-directory-to-an-existing-zip-file