c# recursion folders and files directory - c#

I am trying to retrieve all the files in all the folders I have in a directory .
But the result is quite random ..
I think the foreach is wrong ..
What I don't understand is why ?
Because in all the folders , we check all the files and then display a link buttons of all the files . But actually it's displaying a lot of folders , twice .
var DI = new DirectoryInfo("C://inetpub//wwwroot//ClientPortal//Files//")
.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
foreach (System.IO.DirectoryInfo D1 in DI)
{
System.IO.FileInfo[] fiArr = D1.GetFiles();
foreach (System.IO.FileInfo file in fiArr)
{
LinkButton lktest = new LinkButton();
lktest.Text = D1.Name;
form1.Controls.Add(lktest);
form1.Controls.Add(new LiteralControl("<br>"));
}
}
Can someone help me ?
Thanks a lot !

display a link buttons of all the files
Here you're creating link buttons with the name set to the directory when it sounds like you want the file instead (ie file.Name instead of D1.Name)
lktest.Text = D1.Name;

Does this help?
http://www.dreamincode.net/code/snippet1669.htm
public void GetDirStructure(string path)
{
try
{
DirectoryInfo dir = new DirectoryInfo(path);
DirectoryInfo[] subDirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach(FileInfo fi in files)
{
Console.WriteLine(fi.FullName.ToString());
}
if (subDirs != null)
{
foreach (DirectoryInfo sd in subDirs)
{
GetDirStructure(path + #"\\" + sd.Name);
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}

The first line of code seems like the culprit:
System.IO.DirectoryInfo[] DI = new System.IO.DirectoryInfo("C://inetpub//wwwroot//ClientPortal//Files//").GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
Try using the following:
DirectoryInfo[] DI = new DirectoryInfo("C://inetpub//wwwroot//ClientPortal//File//").GetDirectories();

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.

Creating a log of a backup C#

So I want to log what happens when I backup files but I'm not sure how to make it work for files in subdirectories aswell.
Right now I have this code that works for all files in the selected directory but doesn't work for subdirectory files
private void LogBackup(string sourceDirName, string destDirName)
{
List<string> lines = new List<string>();
string logDestination = this.tbox_LogFiles.Text;
string dateString = DateTime.Now.ToString("MM-dd-yyyy_H.mm.ss");
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
lines.Add("FILES TO COPY:");
lines.Add("--------------");
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files
.Where(f => !extensionsToSkip.Contains(f.Extension) && !filesToSkip.Contains(f.FullName)).ToList())
{
string desttemppath = Path.Combine(destDirName, file.Name);
string sourcetemppath = Path.Combine(sourceDirName, file.Name);
lines.Add("SOURCE FILE:");
lines.Add(sourcetemppath);
lines.Add("DESTINATION FILE:");
lines.Add(desttemppath);
lines.Add("");
}
foreach (DirectoryInfo subdir in dirs
.Where(f => !foldersToSkip.Contains(f.FullName)))
{
//NOT SURE WHAT TO WRITE HERE
}
using (StreamWriter writer = new StreamWriter(logDestination + #"\LOG " + dateString + ".txt"))
{
foreach (string line in lines)
{
writer.WriteLine(line);
}
}
}
Any ideas please?
Include the SearchOption.AllDirectories and you will get all sub directories:
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories("*", SearchOption.AllDirectories);
when you now loop through the directories, you will have also the first level of subdirectories and for each directory just get the files that it contains
foreach (DirectoryInfo subdir in dirs)
{
FileInfo[] files = subdir.GetFiles();
......

How can I find a file within any description of path?

I need find the specific file/folder on my hard drive.
For example i need find a file (do1.bat) and then store the path of the file. But i dont know where can it be stored, so i have to scan all hard drive.
How can i use C# for this?
A simple way would be
var results = Directory.GetFiles("c:\\", "do1.bat", SearchOption.AllDirectories);
This would recurse through all directory and collect all files named do1.bat. Unfortunatly this will not work on complete c:\ since it will throw exceptions if you don't have access to a directory, which surely will happen.
So this is a recursive version:
private static void FindFile(DirectoryInfo currentDirectory, string pattern, List<FileInfo> results)
{
try
{
results.AddRange(currentDirectory.GetFiles(pattern, SearchOption.TopDirectoryOnly));
foreach (DirectoryInfo dir in currentDirectory.GetDirectories("*", SearchOption.TopDirectoryOnly).Where(d => d.Name != "." && d.Name != ".."))
FindFile(dir, pattern, results);
}
catch
{
// probably no access to directory
}
}
This recurses through the directory tree and tries to get the files in a directory and then all subdirectories (except . and ..).
You can use it this way:
DirectoryInfo d = new DirectoryInfo("c:\\");
List<FileInfo> results = new List<FileInfo>();
FindFile(d, "do1.bat", results);
This will find all files named do1.bat in any subdirectory of C:\\ and enlist the FileInfos in the results list.
this should provide you a list of files, matching your search pattern
string[] Result = Directory.GetFiles(#"C:\", "do1.bat", SearchOption.AllDirectories);
Refer: https://msdn.microsoft.com/en-us/library/07wt70x2(v=vs.110).aspx
List<string> lstfilepaths = new List<string>();
public static void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries) // included as per your logic
{
if(fileName == "do1.bat")
{
ProcessFile(fileName);
}
}
// Recurse into subdirectories of this directory.
string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach(string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
}
public static void ProcessFile(string path)
{
lstfilepaths.Add(path);
}
For one file:
public string FindFileByName(string fileName, string searchPath)
{
string resultPath = null;
DirectoryInfo directoryInWhichToSearch = new DirectoryInfo(searchPath);
FileInfo foundFile = directoryInWhichToSearch.GetFiles(fileName, SearchOption.AllDirectories)[0];
resultPath = foundFile.FullName;
return resultPath;
}
You can then use it like this:
string fileFullPath = FindFileByName("do1.bat", #"C:\");

How to copy more than one folder into another folder?

Now here is the problem:
I have a lot of code that all does the same thing. That is, it copies the contents of two folders into a destination folder and merges them in the destination folder. My problem is, I cannot find out (after much Googling) how to actually copy the source directories + contents as opposed to just its contents and sub folders which then end up merged.
It may be how I'm obtaining the directories: I use a Folder Selection Dialog, add the path name to a listbox (To display) and then create a list of (string) directories from the items in the listbox.
Here is the code so far. (Some is from MSDN)
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
if (source.FullName.ToLower() == target.FullName.ToLower())
{
return;
}
// Check if the target directory exists, if not, create it.
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
// Copy each file into it's new directory.
foreach (FileInfo fi in source.GetFiles())
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir =
target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
//This is inside a button click Method
List<string> pathList = new List<string>();
pathList = lstBox.Items.Cast<String>().ToList();
string sourceDirectory;
string targetDirectory;
DirectoryInfo dirSource;
DirectoryInfo dirTarget;
for (int i = 0 ; i < pathList.Count; i++)
{
sourceDirectory = pathList.ElementAt(i);
targetDirectory = browserSave.SelectedPath; //browserSave is the Folder Selection Dialog
dirSource = new DirectoryInfo(sourceDirectory);
dirTarget = new DirectoryInfo(targetDirectory);
CopyAll(dirSource, dirTarget);
}
Annoyingly C# has no Directory.Copy function which would be extremely useful.
Recap.
I Select Folder 1.
I select Folder 2.
I Select Destination Folder.
I Press OK.
Expected Result: Destination Folder has two folders, Folder 1 and Folder 2 inside. Both has all files inside.
Actual Result: Destination Folder has loose files merged, and sub directories of source folders intact. (Which is whats annoying)
I hope this is enough info for you professionals to help with.
The problem is you are never making a new target for your destination -- this will make a new target with the same name as the source for each iteration of the loop and then copy to that target.
for (int i = 0 ; i < pathList.Count; i++)
{
sourceDirectory = pathList.ElementAt(i);
targetDirectory = browserSave.SelectedPath; //browserSave is the Folder Selection Dialog
dirSource = new DirectoryInfo(sourceDirectory);
string targetPath = target.Fullname+
Path.DirectorySeparatorChar+
sourceDirectory.Split(Path.DirectorySeparatorChar).Last());
Directory.CreateDirectory(targetPath);
dirTarget = new DirectoryInfo(targetPath);
CopyAll(dirSource, dirTarget);
}
caveat I did not test so I might have typos, but you get the idea.
Instead of DirectoryInfo pass string as a parameter. See the code below.
private 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);
}
}
}
In main function.
static void Main(string[] args)
{
List<string> directoryNames = new List<string>() // For multiple source folders
{
"C:\\Folder1", "C:\\Folder2"
};
string destDirName = "C:\\Folder3";
foreach (string sourceDirName in directoryNames)
{
DirectoryCopy(sourceDirName, destDirName, true)
}
}
Try the following. You'll obviously need to set the source and destination folders accordingly when you invoke action. Also I would suggest that you do not embed any logic in event handlers.
Hope this helps.
Action<string, string> action = null;
action = (source,dest) =>
{
if(Directory.Exists(source))
{
DirectoryInfo sInfo = new DirectoryInfo(source);
if (!Directory.Exists(dest))
{
Directory.CreateDirectory(dest);
}
Array.ForEach(sInfo.GetFiles("*"), a => File.Copy(a.FullName, Path.Combine(dest,a.Name)));
foreach (string dir in Directory.EnumerateDirectories(source))
{
string sSubDirPath = dir.Substring(source.Length+1,dir.Length-source.Length-1);
string dSubDirPath = Path.Combine(dest,sSubDirPath);
action(dir, dSubDirPath);
}
}
};
action(#"C:\source", #"C:\dest");
This will help you to solve your problem.This function is a generic recursive function for copy folder with or not sub folders with merging.
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);
}
}
}

deleting folder and subfolders in c#

I have a folder that contains sub folders and files with read only attribute (both files and folders). I want to delete this folder with sub-folders and files.
I wrote this code:
static void Main(string[] args)
{
DirectoryInfo mm = new DirectoryInfo(#"c:\ex");
string aa = Convert.ToString(mm);
string[] allFileNames =
System.IO.Directory.GetFiles(aa,
"*.*",
System.IO.SearchOption.AllDirectories);
string[] alldirNames =
System.IO.Directory.GetDirectories(aa,
"*",
System.IO.SearchOption.AllDirectories);
foreach (string filename in allFileNames)
{
FileAttributes attr = File.GetAttributes(filename);
File.SetAttributes(filename, attr & ~FileAttributes.ReadOnly);
}
foreach (string dirname in alldirNames)
{
FileAttributes attr = File.GetAttributes(dirname);
File.SetAttributes(dirname, attr & ~FileAttributes.ReadOnly);
Directory.Delete(dirname , true);
}
FileInfo[] list = mm.GetFiles();
foreach (FileInfo k in list)
{
k.Delete();
}
mm.Delete();
Console.ReadKey();
}
The problem now is that whenever I run the program it gives me the following error:
Could not find a part of the path 'c:\ex\xx\bb'.
What does this error mean?
Directory.Delete(path, true);
Documentation
The previous answer might work, but I believe it will occur with problems in ReadOnly files. But to ensure the deletion and removal of any attribute ReadOnly, the best way to perform this procedure you must be using a method to facilitate the way you were doing, you were not using the correct properties of objects, for example, when using
DirectoryInfo.ToString ()
and use the
DirectoryInfo.GetFiles (aa ...
you were not using the resources the Framework offers within the DirectoryInfo class. See below:
void DirectoryDelete(string strOriginalPath)
{
DirectoryInfo diOriginalPath = new DirectoryInfo(strOriginalPath);
if (diOriginalPath.Attributes.HasFlag(FileAttributes.ReadOnly))
diOriginalPath.Attributes &= ~FileAttributes.ReadOnly;
string[] lstFileList = Directory.GetFiles(strOriginalPath);
string[] lstdirectoryList = Directory.GetDirectories(strOriginalPath);
if (lstdirectoryList.Length > 0)
{
// foreach on the subdirs to the call method recursively
foreach (string strSubDir in lstdirectoryList)
DirectoryDelete(strSubDir);
}
if (lstFileList.Length > 0)
{
// foreach in FileList to be delete files
foreach (FileInfo fiFileInDir in lstFileList.Select(strArquivo => new FileInfo(strArquivo)))
{
// removes the ReadOnly attribute
if (fiFileInDir.IsReadOnly)
fiFileInDir.Attributes &= ~FileAttributes.ReadOnly;
// Deleting file
fiFileInDir.Delete();
}
}
diOriginalPath.Delete();
}
EmptyFolder(new DirectoryInfo(#"C:\your Path"))
Directory.Delete(#"C:\your Path");
private void EmptyFolder(DirectoryInfo directoryInfo)
{
foreach (FileInfo file in directoryInfo.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo subfolder in directoryInfo.GetDirectories())
{
EmptyFolder(subfolder);
}
}

Categories

Resources