I know that if you want to delete a directory you have to delete all of it's files first.
However if you want to delete a directory which contains empty sub-directories, do you have to delete those sub-directories first? or can you just go ahead and delete the main directory?
Directory.Delete set the recurse flag to true, should do the job, no need to empty them first.
Directory.Delete(path, true);
I have just noticed that your tag refers to IsolatedStorage, in which case you will need to enumerate all the files and folders and delete as you go.
How to: Delete Files and Directories in Isolated Storage
You can try to delete recursively:
var path = Path.GetFullPath(#"C:\Temp\DeleteMe");
Directory.Delete(path,true); // true for recursive
This should delete everything including files if you have the proper permissions.
Why check if it is empty or not when you are going to delete it anyway.
You can use the Directory.Delete(yourpath,true) method only if you are sure that there isn't any readonly file in the directory. else it will throw an exception. Instead you can use your own recursive method like this which will first mark the file as normal before deleting it.
public static void DeleteDirectory(string target_dir)
{
string[] files = Directory.GetFiles(target_dir);
string[] dirs = Directory.GetDirectories(target_dir);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string dir in dirs)
{
DeleteDirectory(dir);
}
Directory.Delete(target_dir, false);
}
Related
I'm using below code to make a copy a folder available on a network. This folder has, subfolders and files with total of 455 files and 13 folders and of size 409 MB.
My method is recursively calling itself to create a copy of sub folders and files in it. Overall, this method is taking more than 10 minutes to finish the task and I'm looking to speed up the process.
So far, I've went through different posts but did not find any better solution. Is there a better way to achieve my task or any improvements to my code for a faster execution?
void CopyDirectoryAndFiles(string sourceDirectory, string destinationDirectory, bool recursive)
{
// Get information about the source directory
var dir = new DirectoryInfo(sourceDirectory);
// Check if the source directory exists
if (!dir.Exists)
throw new DirectoryNotFoundException($"Source directory not found:dir.FullName}");
// Cache directories before we start copying
DirectoryInfo[] dirs = dir.GetDirectories();
// Create the destination directory
Directory.CreateDirectory(destinationDirectory);
// Get the files in the source directory and copy to the destination directory
foreach (FileInfo file in dir.GetFiles())
{
string targetFilePath = Path.Combine(destinationDirectory, file.Name);
file.CopyTo(targetFilePath);
}
// If recursive and copying subdirectories, recursively call this method
if (recursive)
{
foreach (DirectoryInfo subDir in dirs)
{
string newDestinationDirectory= Path.Combine(destinationDirectory,subDir.Name);
CopyDirectoryAndFiles(subDir.FullName, newDestinationDirectory, true);
}
}
}
Thanks for your help.
I don't think there's a way to increase performance in a drastic way, but I can suggest a few things to try:
replace foreach w/ Parallel.ForEach to copy data in several streams;
you can use an external tool (e.g. xcopy), which is optimized for the task, and call this tool from your C# code. xcopy can copy folders recursively if you specify the /e flag.
Delete file using C# from directory is holding the process for long time. How to kill process once the file is deleted.
Tried with 2 options of deleting the file,
Option 1:
path = #"C:\temp\a.xml";
File.Delete(path);
Option 2:
path = #"C:\temp\";
DirectoryInfo CVfiles = new DirectoryInfo(path);
foreach (FileInfo CVfile in CVfiles.GetFiles())
{
CVfile.Delete();
}
Update
(from clarification in comments)
path = #"C:\temp\a.xml";
DirectoryInfo CVfiles = new DirectoryInfo(path);
foreach (FileInfo CVfile in CVfiles.GetFiles())
{
CVfile.Delete();
}
Thanks,
You could try
C# delete a folder and all files and folders within that folder
Ultimately the deletion will take as much as deletions needs.
How to kill process once the file is deleted.
You can just exit the program.
I want to create a simple program that can access all the files in the folder, all of which being the same type of file, and then use a for each to rename all of them.
The new name will be IMG### with the ### being incremental. I know how to do this. How do I reference all the images to be used in a for each?
Example:
For Each X in Folder {
rename stuff here for x
}
All I need to know is how to reference file in the spot of x.
You can go about it along this line of thought:
var files = Directory.GetFiles(path, "*.", SearchOption.AllDirectories);
foreach (string item in files)
{
//You can rename by moving the files into their 'new names'.
//The names are full paths
File.Move(oldName, newName);
}
Im trying to copy files from "source" folder to my "destination" folder, without duplicates. I cant use destination folder to compare as it will eventually get deleted from there. I had gotten help here to make a batch file
Robocopy "source" "destination" "*chr.txt*" "*hdr.txt*" /M
that uses attribute to keep track of files copy before. However I need to do this in C# instead. I know theres command to copy
System.IO.File.Copy(sourceFile, destFile, true);
but not sure how to go about being specific on file name "*chr.txt" and taking care of duplicates.
I need to do this in C# instead
Process.Start("robocopy", "source destination chr.txt hdr.txt /M");
Here is a method I created a while ago that has worked well for me (aside from the checking for duplicates part that I just added and haven't tested). Let me know if any parts of it do not work for what you need.
private static void CopyDirectory(string from, string to)
{
var toFileNames = new DirectoryInfo(to)
.GetFiles()
.Select(f => f.Name)
.ToList();
var directory = new DirectoryInfo(from);
var files = directory.GetFiles();
foreach (var file in files)
if (!toFileNames.Contains(file.Name))
file.CopyTo(Path.Combine(to, file.Name));
var subDirectories = directory.GetDirectories();
foreach (var subDirectory in subDirectories)
{
var newDirectory = Directory.CreateDirectory(Path.Combine(to, subDirectory.Name));
CopyDirectory(subDirectory.FullName, newDirectory.FullName);
}
}
Apparently I can't move files on different volumes using Directory.Move.
I have read that I have to copy each file individually to the destination, then delete the source directory.
Do I have any other option?
Regardless of whether or not Directory.Move (or any other function) performed the move between volumes, it would essentially be doing a copy and delete anyway underneath. So if you want a speed increase, that's not going to happen. I think the best solution would be to write your own reusable move function, which would get the volume label (C:,D:) from the to and from paths, and then either perform a move, or copy+delete when necessary.
To my knowledge there is no other way however deleting a directory has a catch: Read Only Files might cause a UnauthorizedAccessException when deleting a directory and all of its contents.
This recurses a directory and unsets all the read only flags. Call before Directory.Delete:
public void removeReadOnlyDeep(string directory)
{
string[] files = Directory.GetFiles(directory);
foreach (string file in files)
{
FileAttributes attributes = File.GetAttributes(file);
if ((attributes & FileAttributes.ReadOnly) != 0)
{
File.SetAttributes(file, ~FileAttributes.ReadOnly);
}
}
string[] dirs = Directory.GetDirectories(directory);
foreach (string dir in dirs)
{
removeReadOnlyDeep(dir);
}
}
An easier option would be, to add a reference to the Microsoft.VisualBasic namespace and use the MoveDirectory method, which can move across volumes.
Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(sourceDirName, destDirName);
Try to use this:
public static void RobustMove(string sourceDirectory, string destDirectory)
{
//move if directories are on the same volume
if (Path.GetPathRoot(source) == Path.GetPathRoot(destination))
{
Directory.Move(source, destination);
}
else
{
CopyDirectoryRecursive(source, destination);
Directory.Delete(source, true);
}
}
You will find CopyDirectoryRecursive function here:
This should be working until you use spanned volume or symbol links to another physical disk.
To be even more robust you can improve this function to use Move until System.IO .Exception is thrown and then to switch to copying and deleting.