Directory.CreateDirectory() does not create folder within ZipFile - c#

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.

Related

Delete Files containing specific Text in Directory and Subdirectories

How to delete Files there names containing a specific string in a Directory and also all Subdirectories?
Given Filenames like:
EA myown EURJPY M15 3015494.mq5
EA myown EURJPY M15 3015494.ex5
EA self EURJPY M15 3098111 fine.mq5
EA self EURJPY M15 3098111 fine.ex5
Given Folderstructures like:
D:\TEMP\MYTEST
D:\TEMP\MYTEST\EURJPY
D:\TEMP\MYTEST\EURJPY\EURJPY_M15
Example: I want to delete ALL Files in all Subdirectories containing this String:
3015494
These Files are copied more than one time down of the Root-Folder "D:\TEMP\MYTEST" and also copied into the Subdirectories.
I try to write a little function for this. But i can delete Files into a given Folder, but not down into Subfolders ...
Last Code from me:
// call my function to delete files ...
string mypath = #"D:\TEMP\MYTEST\";
string myfilecontains = #"xx";
DeleteFile(mypath, true, myfilecontains);
// some code i found here and should delete just Files,
// but only works in Root-Dir.
// Also will not respect my need for Filename contains Text
public static bool DeleteFile(string folderPath, bool recursive, string FilenameContains)
{
//Safety check for directory existence.
if (!Directory.Exists(folderPath))
return false;
foreach (string file in Directory.GetFiles(folderPath))
{
File.Delete(file);
}
//Iterate to sub directory only if required.
if (recursive)
{
foreach (string dir in Directory.GetDirectories(folderPath))
{
//DeleteFile(dir, recursive);
MessageBox.Show(dir);
}
}
//Delete the parent directory before leaving
//Directory.Delete(folderPath);
return true;
}
What i have to change in this Code for my needs?
Or is there a complete different code something more helpfull?
I hope you have some good ideas for me to catch the trick.
DirectoryInfo dir = new DirectoryInfo(mypath);
// get all the files in the directory.
// SearchOptions.AllDirectories gets all the files in subdirectories as well
FileInfo[] files = dir.GetFiles("*.*", SearchOption.AllDirectories);
foreach (FileInfo file in files)
{
if (file.Name.Contains(myfilecontains))
{
File.Delete(file.FullName);
}
}
This is similar to hossein's answer but in his answer if the directory name contains the value of myfilecontains that file will get deleted as well which I would think you don't want.
//get the list of files in the root directory and all its subdirectories:
string mypath = #"D:\TEMP\MYTEST\";
string myfilecontains = #"xx";
var files = Directory.GetFiles(mypath, "*", SearchOption.AllDirectories).ToList<string>();
//get the list of file for remove
var forDelete = files.Where(x => x.Contains(myfilecontains));
//remove files
forDelete.ForEach(x => { File.Delete(x); });
hope this helps!

How to Extract ZIP file from specific path inside ZIP C# Ionic

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.

Ionic Zip cannot zip folder inside folder C#

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);
}

How to copy and paste a whole directory to a new path recursively?

I want to move a directory as a copy/paste routine, by keeping its structure as it is. I am not looking only for the files within all subfolders in a directory then copy/paste them (as this solution), instead I want to clone the whole thing and keep its structure as it is (Tree -> subfolders and files), exactly like a copy and paste routine.
So I found this function that copies a folder full of files to a new path:
Folder -> File(s)
The function behaves as known as the copy/paste routine. It takes SourcePath, DestinationPath and boolean value to OverWriteExisting. Nice and small but too bad it wasn't marked as the actual answer of that question there (recommend a rate).
But what if I want to move a whole directory? In other words, what if I have a folder that has folders of folders of folders of files and etc? And maybe it is unknown the file structure tree size like this:
Folder -> Folder(s) -> ... -> Folder(s) -> File(s)
I am using the below routine to copy/paste a folder that has folders. But here I know that I only have one level of folders so only one foreach loop is required:
foreach (var Folder in DestinationFolder) // here I know that I have only one level of folders to reach the files
{
CopyDirectory(FolderPath, DestinationPath, false); // use that function to copy the files
}
This above function serves this directory structure:
Folder -> Folder(s) -> File(s)
I tried this and it didn't do what I want. I only retrieve all files while it searches all the subfolders. Which is not what I want. I want to keep the subfolders and the original structure as it is. Here I get four files instead of the directory structed as it is, subfolders and their subfolders, subfolders, files. Only four because it removes duplicates which I do not want this to happen because I need all of them.
Here is my current structure(but my question is global to any directory):
Folder -> Folders -> Folders + Files
Here is what the below code does in the new path:
NewFolder -> AllFilesFoundInAnySubfolder
dialog.FileName = dialog.FileName.Replace(".xml", ""); // get the destination path
DirectoryInfo dirInfo = new DirectoryInfo(dialog.FileName);
if (dirInfo.Exists == false)
Directory.CreateDirectory(dialog.FileName);
List<String> EverythingInTheDirectory = Directory
.GetFiles(FileStructure.baseSessionPath + "\\" + SelectedSession.Name, "*.*", SearchOption.AllDirectories).ToList(); // source
foreach (string file in EverythingInTheDirectory)
{
FileInfo mFile = new FileInfo(file);
// to remove name collusion
if (new FileInfo(dirInfo + "\\" + mFile.Name).Exists == false)
mFile.MoveTo(dirInfo + "\\" + mFile.Name);
}
How to move the whole directory with unknown size and keep its structure as it is? Not get only the files from a directory and move them!
Here is an example that will recursively clone a directory to another destination directory.
class Program
{
static void Main(string[] args)
{
CloneDirectory(#"C:\SomeRoot", #"C:\SomeOtherRoot");
}
private static void CloneDirectory(string root, string dest)
{
foreach (var directory in Directory.GetDirectories(root))
{
//Get the path of the new directory
var newDirectory = Path.Combine(dest, Path.GetFileName(directory));
//Create the directory if it doesn't already exist
Directory.CreateDirectory(newDirectory);
//Recursively clone the directory
CloneDirectory(directory, newDirectory);
}
foreach (var file in Directory.GetFiles(root))
{
File.Copy(file, Path.Combine(dest, Path.GetFileName(file)));
}
}
}
A slight variation on code by #hawkstrider .
private static void CloneDirectory(DirectoryInfo source, DirectoryInfo dest) {
foreach (var source_subdir in source.EnumerateDirectories()) {
var target_subdir = new DirectoryInfo(Path.Combine(dest.FullName, source_subdir.Name));
target_subdir.Create();
CloneDirectory(source_subdir, target_subdir);
}
foreach (var source_file in source.EnumerateFiles()) {
var target_file = new FileInfo(Path.Combine(dest.FullName, source_file.Name));
source_file.CopyTo(target_file.FullName, true);
}
}
EDIT:
As #EtiennedeMartel correctly states, the Create() doesn't need the Exists check. ms-docs
Also Enumerations FTW!

How to recursively copy file an folder in .Net?

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

Categories

Resources