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!
Related
My requirement is I have a main folder under which has a set of subfolder. These subfolders are EXPECTED to have a "FileServer.config" file. I need to validate this and Out put a message if the File is missing.
MainFolder--> Contains subfolder 1 ,sub folder 02 , subfolder 03.
So when the user clicks say for example SubFolder01 I want t validate if this file exist in that folder
Currently in the Code I have the code scans for all the folders at once and the output is based on the first folder
string path =# "D:\TEST\PROJ\Repo\";
DirectoryInfo directory = new DirectoryInfo(path);
DirectoryInfo[] subDirectories = directory.GetDirectories();
foreach(DirectoryInfo folder in subDirectories)
{
string subpath = Path.Combine( # "D:\TEST\PROJ\Repo\", folder.Name);
string[] filePaths = Directory.GetFiles(subpath, "fileserver.config");
if(filePaths.Any())
Console.WriteLine(subpath);
}
This will work:
string path = #"D:\TEST\PROJ\Repo\";
DirectoryInfo directory = new DirectoryInfo(path);
foreach (DirectoryInfo folder in directory.GetDirectories())
{
var files = folder.GetFiles("fileserver.config");
if (files.Length > 0)
Console.WriteLine(folder.Name);
}
You said the user clicks on a subdirectory (element), so I assume that you get a concrete folder path. To validate if a certain file is existing in a specific folder try
public bool FileExistsInFolder(string folderPath, string filename)
{
return Directory.Exists(folderPath)
&& Directory.GetFiles(folderPath, fileName).Any();
}
I'm quite stuck on this problem for a while now. I need to copy (update) everything from Folder1\directory1 to Updated\directory1 overwriting same files but not deleting files that already exist on Updated\directory1 but does not exist on Folder1\directory1. To make my question clearer, this is my expected results:
C:\Folder1\directory1
subfolder1
subtext1.txt (2KB)
subfolder2
name.txt (2KB)
C:\Updated\directory1
subfolder1
subtext1.txt (1KB)
subtext2.txt (2KB)
Expected Result:
C:\Updated\directory1
subfolder1
subtext1.txt (2KB) <--- updated
subtext2.txt (2KB)
subfolder2 <--- added
name.txt (2KB) <--- added
I'm currently using Directory.Move(source, destination) but I'm having trouble about the destination part since some of it's destination folder is non-existent. My only idea is to use String.Trim to determine if there's additional folders but I can't really use it since the directories are supposed to be dynamic (there can be more subdirectories or more folders). I'm really stuck. Can you recommend some hints or some codes to get my stuff moving? Thanks!
I got this example from msdn http://msdn.microsoft.com/en-us/library/cc148994.aspx I think this is what you looking for
// 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, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Console.WriteLine("Source path does not exist!");
}
If you need to deal with non existing folder path you should create a new folder
if (System.IO.Directory.Exists(targetPath){
System.IO.Directory.CreateDirectory(targetPath);
}
Parallel fast copying of all files from a folder to a folder with any level of nesting
Tested on copying 100,000 files
using System.IO;
using System.Linq;
namespace Utilities
{
public static class DirectoryUtilities
{
public static void Copy(string fromFolder, string toFolder, bool overwrite = false)
{
Directory
.EnumerateFiles(fromFolder, "*.*", SearchOption.AllDirectories)
.AsParallel()
.ForAll(from =>
{
var to = from.Replace(fromFolder, toFolder);
// Create directories if required
var toSubFolder = Path.GetDirectoryName(to);
if (!string.IsNullOrWhiteSpace(toSubFolder))
{
Directory.CreateDirectory(toSubFolder);
}
File.Copy(from, to, overwrite);
});
}
}
}
// This can be handled any way you want, I prefer constants
const string STABLE_FOLDER = #"C:\temp\stable\";
const string UPDATE_FOLDER = #"C:\temp\updated\";
// Get our files (recursive and any of them, based on the 2nd param of the Directory.GetFiles() method
string[] originalFiles = Directory.GetFiles(STABLE_FOLDER,"*", SearchOption.AllDirectories);
// Dealing with a string array, so let's use the actionable Array.ForEach() with a anonymous method
Array.ForEach(originalFiles, (originalFileLocation) =>
{
// Get the FileInfo for both of our files
FileInfo originalFile = new FileInfo(originalFileLocation);
FileInfo destFile = new FileInfo(originalFileLocation.Replace(STABLE_FOLDER, UPDATE_FOLDER));
// ^^ We can fill the FileInfo() constructor with files that don't exist...
// ... because we check it here
if (destFile.Exists)
{
// Logic for files that exist applied here; if the original is larger, replace the updated files...
if (originalFile.Length > destFile.Length)
{
originalFile.CopyTo(destFile.FullName, true);
}
}
else // ... otherwise create any missing directories and copy the folder over
{
Directory.CreateDirectory(destFile.DirectoryName); // Does nothing on directories that already exist
originalFile.CopyTo(destFile.FullName,false); // Copy but don't over-write
}
});
This was a quick one-off... no error handling was implemented here.
This will help you it is a generic recursive function so always merged subfolders as well.
/// <summary>
/// Directories the copy.
/// </summary>
/// <param name="sourceDirPath">The source dir path.</param>
/// <param name="destDirName">Name of the destination dir.</param>
/// <param name="isCopySubDirs">if set to <c>true</c> [is copy sub directories].</param>
/// <returns></returns>
public static void DirectoryCopy(string sourceDirPath, string destDirName, bool isCopySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirPath);
DirectoryInfo[] directories = directoryInfo.GetDirectories();
if (!directoryInfo.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: "
+ sourceDirPath);
}
DirectoryInfo parentDirectory = Directory.GetParent(directoryInfo.FullName);
destDirName = System.IO.Path.Combine(parentDirectory.FullName, destDirName);
// 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 = directoryInfo.GetFiles();
foreach (FileInfo file in files)
{
string tempPath = System.IO.Path.Combine(destDirName, file.Name);
if (File.Exists(tempPath))
{
File.Delete(tempPath);
}
file.CopyTo(tempPath, false);
}
// If copying subdirectories, copy them and their contents to new location using recursive function.
if (isCopySubDirs)
{
foreach (DirectoryInfo item in directories)
{
string tempPath = System.IO.Path.Combine(destDirName, item.Name);
DirectoryCopy(item.FullName, tempPath, isCopySubDirs);
}
}
}
I'm trying this function, which copies all files from a folder, and relative subfolders with files to another location:
using System.IO;
private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)
{
bool ret = true;
try
{
SourcePath = SourcePath.EndsWith(#"\") ? SourcePath : SourcePath + #"\";
DestinationPath = DestinationPath.EndsWith(#"\") ? DestinationPath : DestinationPath + #"\";
if (Directory.Exists(SourcePath))
{
if (Directory.Exists(DestinationPath) == false)
Directory.CreateDirectory(DestinationPath);
foreach (string fls in Directory.GetFiles(SourcePath))
{
FileInfo flinfo = new FileInfo(fls);
flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
}
foreach (string drs in Directory.GetDirectories(SourcePath))
{
DirectoryInfo drinfo = new DirectoryInfo(drs);
if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false || drs.Substring(drs.Length-8) == "archive")
ret = false;
}
}
else
{
ret = false;
}
}
catch (Exception e)
{
Console.WriteLine("{0} {1} {2}", e.Message, Environment.NewLine + Environment.NewLine, e.StackTrace);
ret = false;
}
return ret;
}
It works good until you have to copy the folder into another location, but when you have to create a folder in itself (In my example I'm doing a subfolder called "archive" to keep track of the last folder files changes) it goes in infinite loops, because it keeps rescanning itself in the Directory.GetDirectories foreach loop, finding the newly created subfolders and going on nesting the same subfolder over and over until it reaches a "Path name too long max 260 charachters limit exception".
I tried to avoid it by using the condition
|| drs.Substring(drs.Length-8) == "archive")
which should check the directory name, but it doesn't seem to work.
I thought than, different solutions like putting a max subfolders depth scan (I.E max 2 subfolders) so it doesn't keep rescanning all the nested folders, but I can't find such property in Directory object.
I cannot copy the whole thing to a temp folder and then into the real folder because the next time I will scan it, it will rescan archive folder too.
I tought about putting all the directory listing in an ArrayList of Directory objects or so so maybe I can check something like DirName or so but I don't know if such property exists.
Any solution?
This is a case where recursion doesn't really work, as the list of directories and files always changes as you copy. A better solution is to get the list of all files and folders in advance.
You can get all files and directories in a tree using the Directory.GetFiles(String,String,SearchOption) and Directory.GetDirectories(String,String,SearchOption) with SearchOption set to SearchOption.AllDirectories. These will return all files and all directories respectively.
You can follow these steps to copy the files:
Get the list of all source directories and sort them in ascending order. This will ensure that parent directories appear before their child directories.
Create the target directory structure by creating the child directories in their sorted order. You won't get any path conflicts as the sort order ensures you always create the parent folders before the child folders
Copy all the source files to the target directories as before. Order doesn't really matter at this point as the target directory structure already exists.
A quick example:
static void Main(string[] args)
{
var sourcePath = #"c:\MyRoot\TestFolder\";
var targetPath = #"c:\MyRoot\TestFolder\Archive\";
var directories=Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
var files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
if(!Directory.Exists(targetPath))
Directory.CreateDirectory(targetPath);
foreach (var directory in directories)
{
var relativePath = GetRelativePath(sourcePath, directory);
var toPath = Path.Combine(targetPath, relativePath);
if (!Directory.Exists(toPath))
{
Directory.CreateDirectory(toPath);
}
}
foreach (var file in files)
{
var relativePath = GetRelativePath(sourcePath, file);
var toPath = Path.Combine(targetPath, relativePath);
if (!File.Exists(toPath))
File.Copy(file,toPath);
}
}
//This is a very quick and dirty way to get the relative path, only for demo purposes etc
private static string GetRelativePath(string rootPath, string fullPath)
{
return Path.GetFullPath(fullPath).Substring(rootPath.Length);
}
I am trying to create a directory and subdirectories and copy files from on one location to another location. The following code works but it doesn't create a parent directory(10_new) if there are sub directories. I am trying to copy all the contents(including subdirectories) from "c:\\sourceLoc\\10" to "c:\\destLoc\\10_new" folder. If "10_new" doesn't exist then I should create this folder. Please assist.
string sourceLoc = "c:\\sourceLoc\\10";
string destLoc = "c:\\destLoc\\10_new";
foreach (string dirPath in Directory.GetDirectories(sourceLoc, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(dirPath.Replace(sourceLoc, destLoc));
if (Directory.Exists(sourceLoc))
{
//Copy all the files
foreach (string newPath in Directory.GetFiles(sourceLoc, "*.*", SearchOption.AllDirectories))
File.Copy(newPath, newPath.Replace(sourceLoc, destLoc));
}
}
From looking at your code, you never check for the existence of the parent folders. You jump to getting all the child folders first.
if (!Directory.Exists(#"C:\my\dir")) Directory.CreateDirectory(#"C:\my\dir");
Here is how to copy all files in a directory to another directory
This is taken from http://msdn.microsoft.com/en-us/library/cc148994.aspx
string sourcePath = "c:\\sourceLoc\\10";
string targetPath = "c:\\destLoc\\10_new";
string fileName = string.Empty;
string destFile = string.Empty;
// 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, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Console.WriteLine("Source path does not exist!");
}
Recursive Directory/Sub-directory
public class RecursiveFileSearch
{
static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();
static void Main()
{
// Start with drives if you have to search the entire computer.
string[] drives = System.Environment.GetLogicalDrives();
foreach (string dr in drives)
{
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);
// Here we skip the drive if it is not ready to be read. This
// is not necessarily the appropriate action in all scenarios.
if (!di.IsReady)
{
Console.WriteLine("The drive {0} could not be read", di.Name);
continue;
}
System.IO.DirectoryInfo rootDir = di.RootDirectory;
WalkDirectoryTree(rootDir);
}
// Write out all the files that could not be processed.
Console.WriteLine("Files with restricted access:");
foreach (string s in log)
{
Console.WriteLine(s);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key");
Console.ReadKey();
}
static void WalkDirectoryTree(System.IO.DirectoryInfo root)
{
System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
// First, process all the files directly under this folder
try
{
files = root.GetFiles("*.*");
}
// This is thrown if even one of the files requires permissions greater
// than the application provides.
catch (UnauthorizedAccessException e)
{
// This code just writes out the message and continues to recurse.
// You may decide to do something different here. For example, you
// can try to elevate your privileges and access the file again.
log.Add(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
}
if (files != null)
{
foreach (System.IO.FileInfo fi in files)
{
// In this example, we only access the existing FileInfo object. If we
// want to open, delete or modify the file, then
// a try-catch block is required here to handle the case
// where the file has been deleted since the call to TraverseTree().
Console.WriteLine(fi.FullName);
}
// Now find all the subdirectories under this directory.
subDirs = root.GetDirectories();
foreach (System.IO.DirectoryInfo dirInfo in subDirs)
{
// Resursive call for each subdirectory.
WalkDirectoryTree(dirInfo);
}
}
}
}
Before doing File.Copy, check to make sure the folder exists. If it doesn't create it.
This function will check if a path exists, if it doesnt, it will create it. If it fails to create it, for what ever reason, it will return false. Otherwise, true.
Private Function checkDir(ByVal path As String) As Boolean
Dim dir As New DirectoryInfo(path)
Dim exist As Boolean = True
If Not dir.Exists Then
Try
dir.Create()
Catch ex As Exception
exist = False
End Try
End If
Return exist
End Function
Remember, all .Net languages compile down to the CLR (common language runtime) so it does not matter if this is in VB.Net or C#. A good way to convert between the two is: http://converter.telerik.com/
It is impossible to copy or move files with C# in windows 7.
It will instead create a file of zero bytes.
I need to Copy folder C:\FromFolder to C:\ToFolder
Below is code that will CUT my FromFolder and then will create my ToFolder.
So my FromFolder will be gone and all the items will be in the newly created folder called ToFolder
System.IO.Directory.Move(#"C:\FromFolder ", #"C:\ToFolder");
But i just want to Copy the files in FromFolder to ToFolder.
For some reason there is no System.IO.Directory.Copy???
How this is done using a batch file - Very easy
xcopy C:\FromFolder C:\ToFolder
Regards
Etienne
This link provides a nice example.
http://msdn.microsoft.com/en-us/library/cc148994.aspx
Here is a snippet
// 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, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
there is a file copy.
Recreate folder and copy all the files from original directory to the new one
example
static void Main(string[] args)
{
DirectoryInfo sourceDir = new DirectoryInfo("c:\\a");
DirectoryInfo destinationDir = new DirectoryInfo("c:\\b");
CopyDirectory(sourceDir, destinationDir);
}
static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination)
{
if (!destination.Exists)
{
destination.Create();
}
// Copy all files.
FileInfo[] files = source.GetFiles();
foreach (FileInfo file in files)
{
file.CopyTo(Path.Combine(destination.FullName,
file.Name));
}
// Process subdirectories.
DirectoryInfo[] dirs = source.GetDirectories();
foreach (DirectoryInfo dir in dirs)
{
// Get destination directory.
string destinationDir = Path.Combine(destination.FullName, dir.Name);
// Call CopyDirectory() recursively.
CopyDirectory(dir, new DirectoryInfo(destinationDir));
}
}
Copying directories (correctly) is actually a rather complex task especially if you take into account advanced filesystem techniques like junctions and hard links. Your best bet is to use an API that supports it. If you aren't afraid of a little P/Invoke, SHFileOperation in shell32 is your best bet. Another alternative would be to use the Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory method in the Microsoft.VisualBasic assembly (even if you aren't using VB).
yes you are right.
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx
has provided copy function ..
or you can use another function
http://msdn.microsoft.com/en-us/library/ms127960.aspx
You'll need to create a new directory from scratch then loop through all the files in the source directory and copy them over.
string[] files = Directory.GetFiles(GlobalVariables.mstrReadsWellinPath);
foreach(string s in files)
{
fileName=Path.GetFileName(s);
destFile = Path.Combine(DestinationPath, fileName);
File.Copy(s, destFile);
}
I leave creating the destination directory to you :-)
You're right. There is no Directory.Copy method. It would be a very powerful method, but also a dangerous one, for the unsuspecting developer. Copying a folder can potentionaly be a very time consuming operation, while moving one (on the same drive) is not.
I guess Microsoft thought it would make sence to copy file by file, so you can then show some kind of progress information. You could iterate trough the files in a directory by creating an instance of DirectoryInfo and then calling GetFiles(). To also include subdirectories you can also call GetDirectories() and enumerate trough these with a recursive method.
A simple function that copies the entire contents of the source folder to the destination folder and creates the destination folder if it doesn't exist
class Utils
{
internal static void copy_dir(string source, string dest)
{
if (String.IsNullOrEmpty(source) || String.IsNullOrEmpty(dest)) return;
Directory.CreateDirectory(dest);
foreach (string fn in Directory.GetFiles(source))
{
File.Copy(fn, Path.Combine(dest, Path.GetFileName(fn)), true);
}
foreach (string dir_fn in Directory.GetDirectories(source))
{
copy_dir(dir_fn, Path.Combine(dest, Path.GetFileName(dir_fn)));
}
}
}
This article provides an alogirthm to copy recursively some folder and all its content
From the article :
Sadly there is no built-in function in System.IO that will copy a folder and its contents. Following is a simple recursive algorithm that copies a folder, its sub-folders and files, creating the destination folder if needed. For simplicity, there is no error handling; an exception will throw if anything goes wrong, such as null or invalid paths or if the destination files already exist.
Good luck!
My version of DirectoryInfo.CopyTo using extension.
public static class DirectoryInfoEx {
public static void CopyTo(this DirectoryInfo source, DirectoryInfo target) {
if (source.FullName.ToLower() == target.FullName.ToLower())
return;
if (!target.Exists)
target.Create();
foreach (FileInfo f in source.GetFiles()) {
FileInfo newFile = new FileInfo(Path.Combine(target.FullName, f.Name));
f.CopyTo(newFile.FullName, true);
}
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) {
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
diSourceSubDir.CopyTo(nextTargetSubDir);
}
}
}
And use like that...
DirectoryInfo d = new DirectoryInfo("C:\Docs");
d.CopyTo(new DirectoryInfo("C:\New"));