I am trying to zip a folder using IonicZip library in C#. It is able to zip .txt, .exe, .pdf etc. in the folder, but not able to zip folder in folder.
It is able to zip MusicLogs.txt and Video.exe but cannot Music folder.Music folder contains some folder also. It doesnt see Music folder even while debugging. My code is :
string zipPath = #"C:\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm") + ".zip"; // zipped file extracts here
string filename = #"E:\"; // the fodler which should be zipped. File must be exist
using (ZipFile zipFile = new ZipFile())
{
zipFile.Password = "asd";
zipFile.Encryption = EncryptionAlgorithm.PkzipWeak;
foreach (string file in Directory.GetFiles(filename)) // this foreach is for getting all files in a folder.
{
zipFile.AddFile(file, "YESMusic"); // set file
}
zipFile.Save(zipPath);
}
Where is the problem ? Need a change in AddFile function ? Thanks
This will work:
using (ZipFile zipFile = new ZipFile())
{
zipFile.Password = "asd";
zipFile.Encryption = EncryptionAlgorithm.PkzipWeak;
// Adding folders in the base directory
foreach (var item in Directory.GetDirectories(filename))
{
string folderName = new DirectoryInfo(item).Name;
zipFile.AddDirectory(item, folderName);
}
// Adding files in the base directory
foreach (string file in Directory.GetFiles(filename))
{
zipFile.AddFile(file);
}
zipFile.Save(zipPath);
}
Related
I have one ZIP file named abc.ZIP
Inside ZIP folder structure is as below:
--abc
---pqr
----a
----b
----c
I want to extract this ZIP at D:/folder_name
But i want to extract only folder and its content named a,b,c. Also folder names are not fixed. I dont want to extract root folder abc and its child folder pqr.
I used following code but its not working:
using (ZipFile zipFile = ZipFile.Read(#"temp.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
entry.Extract(#"D:/folder_name");
}
}
The following should work, but I'm not sure, if it's the best option.
string rootPath = "abc/pqr/";
using (ZipFile zipFile = ZipFile.Read(#"abc.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
if (entry.FileName.StartsWith(rootPath) && entry.FileName.Length > rootPath.Length)
{
string path = Path.Combine(#"D:/folder_name", entry.FileName.Substring(rootPath.Length));
if (entry.IsDirectory)
{
Directory.CreateDirectory(path);
}
else
{
using (FileStream stream = new FileStream(path, FileMode.Create))
entry.Extract(stream);
}
}
}
}
Other option would be to extract the complete file in a temporary directory and move the sub directories to your target directory.
I am trying to zip together all folders and their contents into a zip file. From what I have researched (through StackOverflow and Microsoft), Directory.CreateDirectory(Path) should create the given directory. However, my ZipFile is showing up empty.
For example, I have a folder (C:\Users\smelmo\Desktop\test) with the subfolders (0001, 0002) in it. Within 0001 and 0002 are other documents. I am wanting to zip 0001 and 0002 together within the test folder. This is what I have so far:
// Open the directory of the target folder
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
// Grab each directory within the target folder
foreach (var directoryName in Directory.GetDirectories(strStartPath))
{
// Add each directory to the ZipFile
Directory.CreateDirectory(directoryName);
}
}
This does not produce anything. HOWEVER, I also have code that will grab ALL files within the subfolders and place them in the ZipFile.
// Open the directory of the target folder
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
// Grab each directory within the target folder
foreach (var directoryName in Directory.GetDirectories(strStartPath))
{
//Grab all files in each directory
foreach (var filePath in Directory.GetFiles(directoryName))
{
var fileName = Path.GetFileName(#filePath);
// Place each directory and its repsective files in the zip file
var entry = archive.CreateEntryFromFile(filePath, fileName);
}
}
}
But this does not place subfolders 0001 and 0002 in it, just the CONTENTS of 0001 and 0002. I am wanting 0001 and 0002 and their respective contents.
Edited:
If you are looking for more control, you can just create a function that adds files to a zip archive. You can then use recursion to add any subfolders and files.
First you can define a function that accepts a zip archive to add files to:
public void AddFolderToZip(ZipArchive archive, string rootPath, string path, bool recursive)
{
foreach (var filePath in Directory.GetFiles(path))
{
//Remove root path portion from file path, so entry is relative to root
string entryName = filePath.Replace(rootPath, "");
entryName = entryName.StartsWith("\\") ? entryName.Substring(1) : entryName;
var entry = archive.CreateEntryFromFile(filePath, entryName);
}
if (recursive)
{
foreach (var subPath in Directory.GetDirectories(path))
{
AddFolderToZip(archive, rootPath, subPath, recursive);
}
}
}
Then you can call it using the following code:
string strStartPath = #"C:\Test\zip";
string strZipPath = #"C:\Test\output.zip";
ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create);
bool recursive = true;
foreach (var directoryPath in Directory.GetDirectories(strStartPath))
{
AddFolderToZip(archive, strStartPath, directoryPath, recursive);
}
archive.Dispose();
This code adds each directory it finds in a top level directory. And for each directory it finds, it will use recursion to add any subdirectories or files found within those.
I'm trying to create a zip file from all files in a folder, but can't find any related snippet online. I'm trying to do something like this:
DirectoryInfo dir = new DirectoryInfo("somedir path");
ZipFile zip = new ZipFile();
zip.AddFiles(dir.getfiles());
zip.SaveTo("some other path");
Any help is very much appreciated.
edit: I only want to zip the files from a folder, not it's subfolders.
Referencing System.IO.Compression and System.IO.Compression.FileSystem in your Project
using System.IO.Compression;
string startPath = #"c:\example\start";//folder to add
string zipPath = #"c:\example\result.zip";//URL for your ZIP file
ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Fastest, true);
string extractPath = #"c:\example\extract";//path to extract
ZipFile.ExtractToDirectory(zipPath, extractPath);
To use files only, use:
//Creates a new, blank zip file to work with - the file will be
//finalized when the using statement completes
using (ZipArchive newFile = ZipFile.Open(zipName, ZipArchiveMode.Create))
{
foreach (string file in Directory.GetFiles(myPath))
{
newFile.CreateEntryFromFile(file, System.IO.Path.GetFileName(file));
}
}
Referencing System.IO.Compression and System.IO.Compression.FileSystem in your Project, your code can be something like:
string startPath = #"some path";
string zipPath = #"some other path";
var files = Directory.GetFiles(startPath);
using (FileStream zipToOpen = new FileStream(zipPath, FileMode.Open))
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
{
foreach (var file in files)
{
archive.CreateEntryFromFile(file, file);
}
}
}
In some folders though you may have problems with permissions.
To make your zipfile portable on UNIX system, you should pay attention to:
Compression.ZipFile support for Unix Permissions
For instance, one may use mod "644":
var entry = newFile.CreateEntryFromFile(file, file);
entry.ExternalAttributes |= (Convert.ToInt32("644", 8) << 16);
This does not need loops. For VS2019 + .NET FW 4.7+ did this...
Find ZipFile in Manage Nuget Packages browse, or use
https://www.nuget.org/packages/40-System.IO.Compression.FileSystem/
Then use:
using System.IO.Compression;
As an example, below code fragment will pack and unpack a directory (use false to avoid packing subdirs)
string zippedPath = "c:\\mydir"; // folder to add
string zipFileName = "c:\\temp\\therecipes.zip"; // zipfile to create
string unzipPath = "c:\\unpackedmydir"; // URL for ZIP file unpack
ZipFile.CreateFromDirectory(zippedPath, zipFileName, CompressionLevel.Fastest, true);
ZipFile.ExtractToDirectory(zipFileName, unzipPath);
I have the following script, which take a source folder and copy using FileStream files to another folder.
I need to change it in a way to recursively get any sub-folders and copy their files too.
How to modifythe method?
- source folder
- file
- file
- folder
- file
- file
- folder
- file
- folder
- file
- file
- folder
- file
public static void SynchFolders()
{
DirectoryInfo StartDirectory = new DirectoryInfo(SourceUNC);
DirectoryInfo EndDirectory = new DirectoryInfo(TargetUNC);
foreach (FileInfo file in StartDirectory.EnumerateFiles())
{
using (FileStream SourceStream = file.OpenRead())
{
string dirPath = StartDirectory.FullName;
string outputPath = dirPath.Replace(StartDirectory.FullName, EndDirectory.FullName);
using (FileStream DestinationStream = File.Create(outputPath + "\\" + file.Name))
{
SourceStream.CopyToAsync(DestinationStream);
}
}
}
}
Basically what you need to do is to expand your function slightly such that after copying all files found in a particular directory, it will then search for subfolders within the current folder and recurse into that folder so that the same procedure is carried out on each subfolder.
An example function, based on your original code :
public static void SynchFolders(string SourceUNC, string TargetUNC)
{
DirectoryInfo StartDirectory = new DirectoryInfo(SourceUNC);
DirectoryInfo EndDirectory = new DirectoryInfo(TargetUNC);
// Copy Files
foreach (FileInfo file in StartDirectory.EnumerateFiles())
{
using (FileStream SourceStream = file.OpenRead())
{
string dirPath = StartDirectory.FullName;
string outputPath = dirPath.Replace(StartDirectory.FullName, EndDirectory.FullName);
using (FileStream DestinationStream = File.Create(outputPath + "\\" + file.Name))
{
SourceStream.CopyToAsync(DestinationStream);
}
}
}
// Copy subfolders
var folders = StartDirectory.EnumerateDirectories();
foreach (var folder in folders)
{
// Create subfolder target path by concatenating folder name to original target UNC
string target = Path.Combine(TargetUNC, folder.Name);
Directory.CreateDirectory(target);
// Recurse into the subfolder
SynchFolders(folder.FullName, target);
}
}
Hope this helps
How to: Copy Directories is an article from MSDN showing how to do exactly what you need.
Read this MSDN Tutorial (exacly what you need): http://msdn.microsoft.com/en-us/library/bb762914(v=vs.110).aspx
Note: if you'd like to use SourceStream.CopyToAsync instead of file.CopyTo, just replace it with your original snippet
I'm trying make a program that extracts a specific zip file everytime the program launches.
this is my code to create the zip file:
//creating the file
ZipFile File = new ZipFile(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ABCD.zip");
//Adding files
File.AddFile(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ab.dat", "");
File.AddFile(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\cd.dat", "");
//Save the file
File.Save();
I want to Extract the files ab.dat and cd.dat from ABCD.zip to the .exe file directory automatically.
Thanks for helping.
Taken mostly from the DotNetZip documentation:
private void Extract()
{
//Zip Location
string zipToUnpack = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ABCD.zip";
// .EXE Directory
string unpackDirectory = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
using (ZipFile zip = ZipFile.Read(zipToUnpack))
{
foreach (ZipEntry e in zip)
{
//If filename matches
if (e.FileName == "ab.dat" || e.FileName == "cd.dat")
e.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
}
You can also filter the results using ExtractSelectEntries by selecting the files there:
zip.ExtractSelectedEntries("name = 'ab.dat' OR name = 'cd.dat'", "\", unpackDirectory, ExtractExistingFileAction.OverwriteSilently)
Or selecting all .dat files with a wildcard
zip.ExtractSelectedEntries("name = '*.dat'", "\", unpackDirectory, ExtractExistingFileAction.OverwriteSilently)
Use each ZipEntry's FileName property to see if it has the name you would like to extract.