I have this code
public List<string> GetAllFilesFromFolder(string root, bool searchSubfolders)
{
Queue<string> folders = new Queue<string>();
List<string> files = new List<string>();
folders.Enqueue(root);
while (folders.Count != 0)
{
string currentFolder = folders.Dequeue();
try
{
string[] filesInCurrent = System.IO.Directory.GetFiles(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly);
files.AddRange(filesInCurrent);
}
catch
{
// Do Nothing
}
try
{
if (searchSubfolders)
{
string[] foldersInCurrent = System.IO.Directory.GetDirectories(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly);
foreach (string _current in foldersInCurrent)
{
folders.Enqueue(_current);
}
}
}
catch
{
// Do Nothing
}
}
return files;
}
It list all files from especific directory and search for subdirectories ignoring excepetions to a List<string>
But How can I list the List<string> results to a listbox?
I tried to put
foreach (var foo in files)
{
listbox1.Items.Add(foo);
}
after return files; but for some reason the appears nothing in listbox... I am using visual basic windows forms
Try
listBox1.DataSource = MyList;
(duplicate: C#: easiest way to populate a ListBox from a List)
Related
string selectedPath = GetPath();
var subFolders = AssetDatabase.GetSubFolders(selectedPath);
List<string> paths = new List<string>();
foreach(string path in subFolders)
{
paths.Add(path);
}
For example the subFolders is Assets/My Folder
but under My Folder there are many more subfolders.
AssetDatabase.GetSubFolders don't make recursive it's getting the first sub folder only.
I want to get all the sub folders recursive.
I tried :
List paths = new List();
foreach(string path in subFolders)
{
paths.Add(path);
}
but it's still giving me only the first sub folder.
This is how I'm getting the selected path name in the Assets :
[MenuItem("Assets/Get Path")]
private static string GetClickedDirFullPath()
{
string clickedAssetGuid = Selection.assetGUIDs[0];
string clickedPath = AssetDatabase.GUIDToAssetPath(clickedAssetGuid);
string clickedPathFull = Path.Combine(Directory.GetCurrentDirectory(), clickedPath);
FileAttributes attr = File.GetAttributes(clickedPathFull);
return attr.HasFlag(FileAttributes.Directory) ? clickedPathFull : Path.GetDirectoryName(clickedPathFull);
}
[MenuItem("Assets/Get Path")]
private static string GetPath()
{
string path = GetClickedDirFullPath();
int index = path.IndexOf("Assets");
string result = path.Substring(index);
return result;
}
You could simply make it recursive using List<T>.AddRange like
private static string[] GetSubFoldersRecursive(string root)
{
var paths = new List<string>();
// If there are no further subfolders then AssetDatabase.GetSubFolders returns
// an empty array => foreach will not be executed
// This is the exit point for the recursion
foreach (var path in AssetDatabase.GetSubFolders(root))
{
// add this subfolder itself
paths.Add(path);
// If this has no further subfolders then simply no new elements are added
paths.AddRange(GetSubFoldersRecursive(path));
}
return paths.ToArray();
}
So e.g.
[ContextMenu("Test")]
private void Test()
{
var sb = new StringBuilder();
var folders = SubFolders("Assets");
if(folders.Length > 0)
{
foreach (var folder in SubFolders("Assets"))
{
sb.Append(folder).Append('\n');
}
}
else
{
sb.Append(" << The given path has no subfolders! >>");
}
Debug.Log(sb.ToString());
}
will print out the entire project's folder structure.
For
I get
Assets/Example 1
Assets/Example 1/SubFolder A
Assets/Example 1/SubFolder B
Assets/Example 1/SubFolder C
Assets/Example 2
Assets/Example 2/SubFolder A
Assets/Example 2/SubFolder A/SubSubFolder A
So in your case it would be
string selectedPath = GetPath();
var folders = SubFolders(selectedPath);
foreach(var path in folders)
{
...
}
Try this code for get recursive folder path
//this is your code
string selectedPath = GetPath();
var subFolders = AssetDatabase.GetSubFolders(selectedPath);
List<string> paths = new List<string>();
if(subFolders != null)
{
foreach(string path in subFolders)
{
GetAllRecursiveFolder(path,ref paths);
}
}
else
{
paths.add(selectedPath);
}
public void GetAllRecursiveFolder(string currentPath,ref List<string> paths)
{
var subFolders = AssetDatabase.GetSubFolders(currentPath);
if(subFolders != null)
{
foreach(string path in subFolders)
{
GetAllRecursiveFolder(path,ref paths);// Get recursive folder path, and stored in ref variable
}
}
else
{
paths.add(currentPath);
}
}
I'm trying to pull together a treeview with folders of mixed classes. The root folders are one class and subfolders are another, like this:
Root Folder #1 <-- DirectoryItem class
--Sub Folder <-- SubDirectoryItem class
----file <-- FileItem class
Root Folder #2 <-- DirectoryItem class
--Sub Folder <-- SubDirectoryItem class
----file <-- FileItem class
I've been attempting to combine two different recursive methods so the subfolders are retrieved as "SubDirectoryItems" instead of "DirectoryItem" I'll spare that code attempt due to lack of clarify, but I'm wondering if there's a better approach?
class ItemProvider
{
public List<Item> GetItems(string path, SearchOption searchOption)
{
var items = new List<Item>();
var dirInfo = new DirectoryInfo(path);
foreach (var directory in dirInfo.GetDirectories("*.*", SearchOption.TopDirectoryOnly))
{
var item = new DirectoryItem
{
Name = directory.Name,
Path = directory.FullName,
Items = GetItems(directory.FullName, SearchOption.AllDirectories)
};
items.Add(item);
}
foreach (var subdirectory in dirInfo.GetDirectories("*.*", SearchOption.TopDirectoryOnly))
{
var item = new SubDirectoryItem()
{
Name = subdirectory.Name,
Path = subdirectory.FullName,
Items = GetItems(subdirectory.FullName, SearchOption.AllDirectories)
};
items.Add(item);
}
foreach (var file in dirInfo.GetFiles())
{
var item = new FileItem
{
Name = file.Name,
Path = file.FullName
};
items.Add(item);
}
return items;
}
}
}
I was able to figure it out. I made the first list TopDirectoryOnly then pulled in the rest of the items via a 2nd list for AllDirectories. Here's the code in case it helps any other beginners (like me):
class ItemProvider
{
public List<Item> GetItems(string path, SearchOption searchOption)
{
var items = new List<Item>();
var dirInfo = new DirectoryInfo(path);
foreach (var directory in dirInfo.GetDirectories("*.*", SearchOption.TopDirectoryOnly))
{
var item = new DirectoryItem
{
Name = directory.Name,
Path = directory.FullName,
Items = GetSubItems(directory.FullName, SearchOption.AllDirectories)
};
items.Add(item);
}
return items;
}
public List<Item> GetSubItems(string path, SearchOption searchOption)
{
var items = new List<Item>();
var dirInfo = new DirectoryInfo(path);
foreach (var subdirectory in dirInfo.GetDirectories("*.*", SearchOption.AllDirectories))
{
var item = new SubDirectoryItem()
{
Name = subdirectory.Name,
Path = subdirectory.FullName,
Items = GetSubItems(subdirectory.FullName, SearchOption.AllDirectories)
};
items.Add(item);
}
foreach (var file in dirInfo.GetFiles())
{
var item = new FileItem
{
Name = file.Name,
Path = file.FullName
};
items.Add(item);
}
return items;
}
}
I have a list of strings which holds file paths.
List<string> allFilesWithPathList = new List<string>();
allFilesWithPathList.Add(#"G:\Test\A.sql");
allFilesWithPathList.Add(#"G:\Test\B.sql");
allFilesWithPathList.Add(#"G:\Test\C.sql");
return allFilesWithPathList;
I have another list which holds a subset of files – but it has only the file name; not the path.
List<string> excludeList = new List<string>();
excludeList.Add("B.sql");
Now I need to get files from allFilesWithPathList that is not present in excludeList. Currently I am doing the following, using EXCEPT, after creating another list with file names only.
List<string> allFileNamesOnlyList = new List<string>();
foreach (string fileNameWithPath in allFilesWithPathList)
{
//Remove path and get only file name
int pos = fileNameWithPath.LastIndexOf(#"\") + 1;
string value = fileNameWithPath.Substring(pos, fileNameWithPath.Length - pos);
allFileNamesOnlyList.Add(value);
}
//EXCEPT logic
List<string> eligibleListToProcess = allFileNamesOnlyList.Except(excludeList).ToList();
What is the best way in LINQ to get this logic working without introducing another list like the above?
Note: I am using .Net 4.5
Complete code
class Program
{
static void Main(string[] args)
{
List<string> allFilesWithPathList = GetAllFilesWithPath();
List<string> excludeList = new List<string>();
excludeList.Add("B.sql");
List<string> allFileNamesOnlyList = new List<string>();
foreach (string fileNameWithPath in allFilesWithPathList)
{
//Remove path and get only file name
int pos = fileNameWithPath.LastIndexOf(#"\") + 1;
string value = fileNameWithPath.Substring(pos, fileNameWithPath.Length - pos);
allFileNamesOnlyList.Add(value);
}
//EXCEPT logic
List<string> eligibleListToProcess = allFileNamesOnlyList.Except(excludeList).ToList();
//Print all eligible files
foreach (string s in eligibleListToProcess)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
public static List<string> GetAllFilesWithPath()
{
List<string> allFilesWithPathList = new List<string>();
allFilesWithPathList.Add(#"G:\Test\A.sql");
allFilesWithPathList.Add(#"G:\Test\B.sql");
allFilesWithPathList.Add(#"G:\Test\C.sql");
return allFilesWithPathList;
}
}
allFilesWithPathList.Where(path => !allFileNamesOnlyList.Contains(Path.GetFileName(path));
There are two improvements here.
Path.GetFileName is much better than splitting the path yourself.
IEnumerable.Where in conjunction with ICollection.Contains to actually query the list in a succinct and easy to read way.
This should work
allFilesWithPathList.Where(x => !excludeList.Any(y => x.EndsWith(y)))
I have this method and get the above error on the line words.Add(rows); can anyone help? Thanks - Ben
private static IEnumerable<string> LoadWords(String filePath)
{
List<String> words = new List<String>();
try
{
foreach (String line in File.ReadAllLines(filePath))
{
string[] rows = line.Split(',');
words.Add(rows);
}
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.Message);
}
return words;
}
Instead of
words.Add(rows);
use this :
words.AddRange(rows);
rows is a string array containing multiple strings, so you have to add them with AddRange().
Change it to this
words.AddRange(rows);
You issue is that you are adding an array of items, not a single element.
You use AddRange() when adding a collection that implements System.Collections.Generic.IEnumerable<T>
See documentation here http://msdn.microsoft.com/en-us/library/z883w3dc.aspx
You are trying to add a string array to a list that takes a string.
Try words.AddRange(rows);
u r trying to add string of array in a list of array
private static IEnumerable<string> LoadWords(String filePath)
{
List<String> words = new List<String>();
try
{
foreach (String line in File.ReadAllLines(filePath))
{
string[] rows = line.Split(',');
foreach(string str in rows)
words.Add(str);
}
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.Message);
}
return words;
}
You are using the wrong method. You want the AddRange method.
words.AddRange(rows);
Have a try of this:
words.AddRange(rows);
.Add will take another string, not an array of strings.
Try .AddRange instead.
private static IEnumerable<string> LoadWords(String filePath)
{
List<String> words = new List<String>();
try
{
foreach (String line in File.ReadAllLines(filePath))
{
string[] rows = line.Split(',');
foreach (String word in rows)
{
words.Add(word);
}
}
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.Message);
}
return words;
}
I have two folders A and B..Inside A multiple files are there and inside B multiple files are there..I have to check files in A with files in B for identical files...
I tried like this for a particular file name
void DirSearch(string sDir)
{
List<string> lstFilesFound = new List<string>();
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d,"MsBuild_Tracker.proj")
{
lstFilesFound.Add(f);
}
DirSearch(d);
}
}
It is working..I tried like this for two folders
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetDirectories(dDir))
{
foreach (string g in Directory.GetFiles(d, f))
{
lstFilesFound.Add(g);
}
DirSearch(d, f);
}
}
It is not working...Any suggestion??
If you're using .NET 4, you can use DirectoryInfo and EnumerateFiles(). Then you can use LINQ to join the two directories to get the common files between the two directories.
var dir1 = new DirectoryInfo(#"c:\temp1");
var dir2 = new DirectoryInfo(#"c:\temp2");
var filesinboth = from f1 in dir1.EnumerateFiles()
join f2 in dir2.EnumerateFiles() on f1.Name equals f2.Name
select f1.Name;
or you can use where if you want additional conditions to apply.
var filesinboth = from f1 in dir1.EnumerateFiles()
from f2 in dir2.EnumerateFiles()
where f1.Name == f2.Name // and some other condition
select f1.Name;
These will both give you stream of strings. If you need the actual FileInfo instances, change the select part of the query to return f1 instead of f1.Name.
If you're using .NET 3.5, you need to use GetFiles() instead, which returns FileInfo[]. So the queries will look like this:
var filesinboth = from f1 in dir1.GetFiles()
join f2 in dir2.GetFiles() on f1.Name equals f2.Name
select f1.Name;
and
var filesinboth = from f1 in dir1.GetFiles()
from f2 in dir2.GetFiles()
where f1.Name == f2.Name // and some other condition
select f1.Name;
Why don't use just something like this (without recursion) ?
public static IEnumerable<string> GetMachingFiles(string pathA, string pathB)
{
var matchingFiles = new HashSet<string>();
var allAfiles = Directory.GetFiles(pathA, "*", SearchOption.AllDirectories);
foreach (var file in allAfiles)
{
foreach (var mathcFile in Directory.GetFiles(pathB, Path.GetFileName(file), SearchOption.AllDirectories))
matchingFiles.Add(mathcFile);
}
return matchingFiles;
}
Of course this solution suffers a performance decay in case of many files, because Directory.GetFiles navigates all files even when you pass a restrictive pattern.
To be more faster you could use LINQ as pointed out in Brian Rasmussen's answer
EDIT:
a faster example using LINQ (.NET 3.5):
public static IEnumerable<string> GetMachingFilesFast(string pathA, string pathB)
{
DirectoryInfo dirA = new DirectoryInfo(pathA);
DirectoryInfo dirB = new DirectoryInfo(pathB);
var filesA = dirA.GetFiles("*",SearchOption.AllDirectories);
var filesB = dirB.GetFiles("*", SearchOption.AllDirectories);
var matchingFiles =
filesA.Where(fA => filesB.Any(
fB => fA.Name == fB.Name
// && fA.LastWriteTime == fB.LastWriteTime
)
)
.Select(x => x.Name);
return matchingFiles;
}
try below code , you need to change path of files
DirectoryInfo dinfoTemp1 = new DirectoryInfo(#"C:\\Temp1");
DirectoryInfo dinfoTemp2 = new DirectoryInfo(#"C:\\Temp2");
FileInfo[] lstTemp1 = dinfoTemp1.GetFiles();
List<string> ui = lstTemp1.Where(
x => dinfoTemp2.GetFiles().
Where(y => y.Name.Contains(x.Name)).Count() > 0).
Select(x=>x.Name).ToList();
What you are basically doing is:
setting directory to var d like C://
Setting directory to var f like My Documents
Getting files that have the name My Documents in C://
and if you find any which I highly doubt, you add it to your list.
The first one works because;
sets the directory to var d like C://
gets the file that is named MsBuild_Tracker.proj in C://
adds it to the list.
Tell us what you need and maybe we can help..
Maybe compare (for a non-linq version) --
namespace RecursiveDirCompare
{
class Program
{
static List initialFiles = new List();
static string initRoot = #"root";
static string initCompare = #"compare";
static void Main(string[] args)
{
Directory.SetCurrentDirectory( #"C:\Temp\test\");
initRoot = #"root";// args[0];
initCompare = #"compare";// args[1];
AddFilesToInitialList(initRoot);
CompareWithInitialList(initCompare);
Console.ReadKey();
}
static void AddFilesToInitialList(string root)
{
foreach (string file in Directory.GetFiles(root))
{
initialFiles.Add(file.Replace(initRoot, ""));
}
foreach (string directory in Directory.GetDirectories(root))
{
AddFilesToInitialList(directory);
}
}
static void CompareWithInitialList(string root)
{
foreach (string file in Directory.GetFiles(root))
{
if(initialFiles.Contains(file.Replace(initCompare, "")))
{
Console.WriteLine(file + " is found in both");
}
}
foreach (string directory in Directory.GetDirectories(root))
{
CompareWithInitialList(directory);
}
}
}
}