How to compare two folders for similar files based on name in C#?
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 DirSe开发者_运维技巧arch(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 string
s. 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); } } } }
精彩评论