Extract zip file and overwrite (in the same directory - C#) - c#

I'm starting some C# stuff, and i would like to extract and force to overwrite all files from a zip archive. I know that there are many other solution in Stack, but nothing works for me :/
i've tried this method:
try
{
string zipPath = (Directory.GetCurrentDirectory() + "\\" + "my_zip");
Console.WriteLine("Zip's path: " + zipPath);
string extractPath = Directory.GetCurrentDirectory();
ZipFile.ExtractToDirectory(zipPath, extractPath);
return (0); // 0 all fine
}
catch (Exception)
{
return (1); // 1 = extract error
}
This extractor works fine, but doesn't allow me to overwrite files meanwhile extraction, and it returns error and exceptions ... i've tried to take a look at MS-Documention, without success ...
someone know how does it work ?

Try something like this. Away from my dev box so this may require some tweaking, just writing it from memory.
Edit: As someone mentioned you can use ExtractToFile which has an overwrite option. ExtractToDirectory does not.
Essentially you unzip to a temporary folder then check if an unzipped file's name already exists in the destination folder. If so, it deletes the existing file and moves the newly unzipped one to the destination folder.
try
{
string zipPath = (Directory.GetCurrentDirectory() + "\\" + "my_zip");
Console.WriteLine("Zip's path: " + zipPath);
//Declare a temporary path to unzip your files
string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "tempUnzip");
string extractPath = Directory.GetCurrentDirectory();
ZipFile.ExtractToDirectory(zipPath, tempPath);
//build an array of the unzipped files
string[] files = Directory.GetFiles(tempPath);
foreach (string file in files)
{
FileInfo f = new FileInfo(file);
//Check if the file exists already, if so delete it and then move the new file to the extract folder
if (File.Exists(Path.Combine(extractPath,f.Name)))
{
File.Delete(Path.Combine(extractPath, f.Name));
File.Move(f.FullName, Path.Combine(extractPath, f.Name));
}
else
{
File.Move(f.FullName, Path.Combine(extractPath, f.Name));
}
}
//Delete the temporary directory.
Directory.Delete(tempPath);
return (0); // 0 all fine
}
catch (Exception)
{
return (1); // 1 = extract error
}
Edit, in the event directories are unzipped (again, may need to be tweaked, I didn't test it):
try
{
string zipPath = (Directory.GetCurrentDirectory() + "\\" + "my_zip");
Console.WriteLine("Zip's path: " + zipPath);
//Declare a temporary path to unzip your files
string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "tempUnzip");
string extractPath = Directory.GetCurrentDirectory();
ZipFile.ExtractToDirectory(zipPath, tempPath);
//build an array of the unzipped directories:
string[] folders = Directory.GetDirectories(tempPath);
foreach (string folder in folders)
{
DirectoryInfo d = new DirectoryInfo(folder);
//If the directory doesn't already exist in the destination folder, move it to the destination.
if (!Directory.Exists(Path.Combine(extractPath,d.Name)))
{
Directory.Move(d.FullName, Path.Combine(extractPath, d.Name));
continue;
}
//If directory does exist, iterate through the files updating duplicates.
else
{
string[] subFiles = Directory.GetFiles(d.FullName);
foreach (string subFile in subFiles)
{
FileInfo f = new FileInfo(subFile);
//Check if the file exists already, if so delete it and then move the new file to the extract folder
if (File.Exists(Path.Combine(extractPath, d.Name, f.Name)))
{
File.Delete(Path.Combine(extractPath, d.Name, f.Name));
File.Move(f.FullName, Path.Combine(extractPath, d.Name, f.Name));
}
else
{
File.Move(f.FullName, Path.Combine(extractPath, d.Name, f.Name));
}
}
}
}
//build an array of the unzipped files in the parent directory
string[] files = Directory.GetFiles(tempPath);
foreach (string file in files)
{
FileInfo f = new FileInfo(file);
//Check if the file exists already, if so delete it and then move the new file to the extract folder
if (File.Exists(Path.Combine(extractPath,f.Name)))
{
File.Delete(Path.Combine(extractPath, f.Name));
File.Move(f.FullName, Path.Combine(extractPath, f.Name));
}
else
{
File.Move(f.FullName, Path.Combine(extractPath, f.Name));
}
}
Directory.Delete(tempPath);
return (0); // 0 all fine
}

Related

Copy specific Folder with 3 Files only to New Folder

One Question about coding (Visual Studio C# WindowsformApplication) There have Two folder: (Source and Target) and I build 1 button "Copy".
In "Source" folder have random folders such as "20190401", "20190402", "20190403", "20180401", "20170401" and "20160401". Every these folders have [10] .txt files. What is the coding if I only want to copy all "201904**" folders with [3] .txt files inside it to "Target" folder? Here is my code for now.
Code
** private void button1_Click
{
string FROM_DIR = "C:/Users/5004117928/Desktop/Source";
string TO_DIR = "C:/Users/5004117928/Desktop/Target/";
DirectoryInfo diCopyForm = new DirectoryInfo(FROM_DIR);
DirectoryInfo[] fiDiskfiles = diCopyForm.GetDirectories();
string directname = "201904";
string filename = ".txt";
foreach (DirectoryInfo newfile in fiDiskfiles)
{
try
{
if (newfile.Name == "2019")
{
foreach (DirectoryInfo direc in newfile.GetDirectories())
if (direc.Name.StartsWith(directname))
{
int count = 0;
foreach (FileInfo file in direc.GetFiles())
{
if (file.Name.EndsWith(filename))
{
count++;
}
}
if (count == 3)
{
DirectoryCopy(direc.FullName,Path.Combine(TO_DIR,direc.Name), true);
count = 0;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
MessageBox.Show("success");
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}**
I expect after I click a button,
output is automatically copy all folders Name Start With "201904**" with [3] text files inside from "Source" folder to "target" folder.
I reckon you can search the directory with names directly using linq and can copy the sub folders/files inside it like below. It will give you the flexibility of filtering folders/files/skipping/taking n folders/files
string FROM_DIR = "C:/Users/5004117928/Desktop/Source";
string TO_DIR = "C:/Users/5004117928/Desktop/Target/";
string searchText = "201904";
string extension = "txt";
IEnumerable<string> dirs = Directory.EnumerateDirectories(FROM_DIR, "*", SearchOption.AllDirectories)
.Where(dirPath=>Path.GetFileName(dirPath.TrimEnd(Path.DirectorySeparatorChar)).StartsWith(searchText));
foreach (string dir in dirs)
{
string destDirPath = dir.Replace(FROM_DIR, TO_DIR);
if (!Directory.Exists(destDirPath))
Directory.CreateDirectory(destDirPath);
//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.EnumerateFiles(dir, string.format("*.{0}",extension),
SearchOption.AllDirectories))// Here you can skip/take n files if u need
File.Copy(newPath, newPath.Replace(FROM_DIR, TO_DIR), true);
}
Have tested with sub folders and files inside source folder as well. Hope it helps.

Why is File.Move not working as expected?

I am trying to move all files from rootFolderPath to destinationPath
try
{
string rootFolderPath = #"D:\Log_siteq\";
if (!Directory.Exists(Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString())))
{
System.IO.Directory.CreateDirectory(Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString()));
}
string destinationPath = Path.Combine(#"D:\Log_takaya\" + comboBox1.SelectedItem.ToString() );
string fileTypes = #"*.*";
string[] fileList = System.IO.Directory.GetFiles(rootFolderPath, fileTypes);
foreach (string file in fileList)
{
string ext = Path.GetExtension(file);
string destination = Path.Combine(destinationPath,file);
File.Move( file,destination);
MessageBox.Show(file);
MessageBox.Show(destination);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
Apparently MessageBox.Show(file); shows me my root folder path ( as is normal) but MessageBox.Show(destination); is showing me the same thing.
What gives? It just moves my file from my root folder in the same folder.Am I not getting something?
You are combining the destinationPath with the complete file path of file:
string destination = Path.Combine(destinationPath, file);
which will just overwrite the destination with the original file path (because "C:\desitnation\C:\source\filename.txt" isn't a valid path).
Instead, you need only the file name like this:
string destination = Path.Combine(destinationPath, Path.GetFileName(file));

Move Folder and its contents to Other Folder

I am working on an asp.net application where i have to move any Folder and its contents to another. Suppose i have a Main folder and in that folder there is 3 subfolders. In each subfolder there is a file. I want to move folder and all its contents to another place. For this i used the following code
if (!Directory.Exists(#"E:\Sunny\C#FolderCopy"))
{
Directory.CreateDirectory(#"E:\Sunny\C#FolderCopy");
Directory.Move(#"E:\Sunny\C#Folder\", #"E:\Sunny\C#FolderCopy\");
}
But when the control reaches to move function The error comes as
Cannot create a file when that file already exists.
How to solve this
Directory.Move already creates the folder for you. You only need to adjust to the following:
if (!Directory.Exists(#"E:\Sunny\C#FolderCopy"))
{
Directory.Move(#"E:\Sunny\C#Folder\", #"E:\Sunny\C#FolderCopy\");
}
If you want to copy the folder (as indicated by your comment) you can use FileSystem.CopyDirectory. It is located in a Visual Basic namespace but that should be of no concern at all:
using Microsoft.VisualBasic.FileIO;
if (!Directory.Exists(#"E:\Sunny\C#FolderCopy"))
{
FileSystem.CopyDirectory(#"E:\Sunny\C#Folder\", #"E:\Sunny\C#FolderCopy\");
}
Or use this method (taken from msdn):
DirectoryCopy(".", #".\temp", true);
private static void DirectoryCopy(
string sourceDirName, string destDirName, bool copySubDirs)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
// If the destination directory does not exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the file contents of the directory to copy.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
// Create the path to the new copy of the file.
string temppath = Path.Combine(destDirName, file.Name);
// Copy the file.
file.CopyTo(temppath, false);
}
// If copySubDirs is true, copy the subdirectories.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
// Create the subdirectory.
string temppath = Path.Combine(destDirName, subdir.Name);
// Copy the subdirectories.
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
Recursive Files Move.
Call this method and all it do.
public static void MoveDirectory(string source, string target)
{
var sourcePath = source.TrimEnd('\\', ' ');
var targetPath = target.TrimEnd('\\', ' ');
var files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories)
.GroupBy(s=> Path.GetDirectoryName(s));
foreach (var folder in files)
{
var targetFolder = folder.Key.Replace(sourcePath, targetPath);
Directory.CreateDirectory(targetFolder);
foreach (var file in folder)
{
var targetFile = Path.Combine(targetFolder, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Move(file, targetFile);
}
}
Directory.Delete(source, true);
}

How to copy selected folders, subfolders and files from openFileDialog in c#

I have a function that is suposed to copy all folders, subfolders files selected from openFileDialog from a location to another:
I've made this function to copy all the selected paths:
public void CopiarFicheiros(string CopyTo, List<string> FilesToCopy )
{
foreach (var item in FilesToCopy)
{
string DirectoryName = Path.GetDirectoryName(item);
string Copy = Path.Combine(CopyTo, DirectoryName);
if (Directory.Exists(Copy) && DirectoryName.ToLower() != "newclient" && DirectoryName.ToLower() != "newservice")
{
Directory.CreateDirectory(Copy);
File.Copy(item, Copy + #"\" + Path.GetFileName(item), true);
}
else File.Copy(item, CopyTo + #"\" + Path.GetFileName(item), true);
}
}
The logic is full of flaws and I'm running out of time and can't seem to find a proper solution to this.
This is how I get the selected files and folders from the dialog:
private List<string> GetFiles()
{
var Files = new List<string>();
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string sFileName = openFileDialog.FileName;
string[] arrAllFiles = openFileDialog.FileNames;
Files = arrAllFiles.ToList();
}
return Files;
}
Does anyone have a better solution or a clue to what I need to change to successfully do this?
Any help is highly appreciated, thank you
Don't use OpenFileDialog to choose the folder. As the name suggests, it not made for that task. You want the FolderBrowserDialog class for this task.
How to: Copy Directories:
// Copy from the current directory, include subdirectories.
DirectoryCopy(".", #".\temp", true);
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}

How to create a same directory as source copying a file in c#

I am copying file from my server.map path to some folder in C:\ But When i am copying my file i want that it create the folder path same it is in server.map path with file to copy
Here is my code where i am copying file but it is not creating the same directory which i want.
public void CopyFiles()
{
string Filename = "PSK_20150318_1143342198885.jpg";
string sourcePath = Server.MapPath("~/UserFiles/Images/croppedAvatar/");
string targetPath = #"C:\MyCopyFIle\";
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath,Filename);
string destFile = System.IO.Path.Combine(targetPath,Filename);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
// To copy a file to another location and
// overwrite the destination file if it already exists.
System.IO.File.Copy(sourceFile, destFile, true);
// To copy all the files in one directory to another directory.
// Get the files in the source folder. (To recursively iterate through
// all subfolders under the current directory, see
// "How to: Iterate Through a Directory Tree.")
// Note: Check for target path was performed previously
// in this code example.
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
Filename = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Debug.WriteLine("Source path does not exist!");
}
}
Now the source path contain /userfiles/images/croppedavatar directory in it when I am copying it in c:\MyCopyFile I want it create a folder structure like c:\MyCopyFile\UserFile\Images\CroppedAvatar
you have to check each file structure and create the same on destination and then copy file as
public void CopyFiles(string srcpath, List<string> sourcefiles, string destpath)
{
DirectoryInfo dsourceinfo = new DirectoryInfo(srcpath);
if (!Directory.Exists(destpath))
{
Directory.CreateDirectory(destpath);
}
DirectoryInfo dtargetinfo = new DirectoryInfo(destpath);
List<FileInfo> fileinfo = sourcefiles.Select(s => new FileInfo(s)).ToList();
foreach (var item in fileinfo)
{
string destNewPath = CreateDirectoryStructure(item.Directory.FullName, destpath) + "\\" + item.Name;
File.Copy(item.FullName, destNewPath);
}
}
public string CreateDirectoryStructure(string newPath, string destPath)
{
Queue<string> queue = new Queue<string>(newPath.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries));
queue.Dequeue();
while (queue.Count>0)
{
string dirName = queue.Dequeue();
if(!new DirectoryInfo(destPath).GetDirectories().Any(a=>a.Name==dirName))
{
Directory.CreateDirectory(destPath + "\\" + dirName);
destPath += "\\" + dirName;
}
}
return destPath;
}
You can simply create a folder structure using FileInfo Class:
string path=#"c:/MyCopyFile/UserFile/Images/CroppedAvatar/";
FileInfo file = new FileInfo(path);
file.Directory.Create();
This will create a directory where you can copy what you want to.
You can change your code like following
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
Filename = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath, Filename);
string path = #"C:/MyCopyFile/UserFiles/Images/croppedAvatar/";
FileInfo file = new FileInfo(path);
file.Directory.Create();
string folderStructurePath = #"C:/MyCopyFile/UserFiles/Images/croppedAvatar/" + Filename;
System.IO.File.Copy(sourceFile, folderStructurePath, true);
}
}

Categories

Resources