It depends how robust it needs to be... if this is a one-off task,
then a simple dictionary over the name (key) and list of matching
paths (value) would probably suffice, but it wouldn't be very elegant
(or efficient) and would have a lot of false-positives without more
restriction than just the name. Very crude, but it works.
Marc
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
// lazy hacky static lookups
static readonly Dictionary<string, List<string>allFiles = new
Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
static int counter = 0;
static void Main()
{
// find available drives
List<stringfixedDisks = new List<string>();
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.IsReady && drive.DriveType == DriveType.Fixed)
{
fixedDisks.Add(drive.Name);
}
}
Walk(fixedDisks.ToArray());
// output duplicates
foreach (KeyValuePair<string, List<string>pairs in allFiles)
{
if (pairs.Value.Count 1)
{
Console.WriteLine("***" + pairs.Key);
foreach (string path in pairs.Value)
{
Console.WriteLine(path);
}
}
}
}
static void Walk(string[] paths)
{
// expolde the gives paths
for(int i = 0; i < paths.Length; i++) {
string path = paths[i];
if ((counter++ % 100) == 0)
{ // cheap progress indicator
Console.WriteLine(path);
}
try
{// look at files
string[] files = Directory.GetFiles(path);
for (int j = 0; j < files.Length; j++)
{
string file = files[j], key =
Path.GetFileName(file);
List<stringlookups;
if (!allFiles.TryGetValue(key, out lookups))
{
lookups = new List<string>();
allFiles.Add(key, lookups);
}
lookups.Add(file);
}
}
catch(Exception ex)
{
Console.Error.WriteLine(path + ":" + ex.Message);
}
try
{ // look at sub-dirs
Walk(Directory.GetDirectories(path));
}
catch (Exception ex)
{
Console.Error.WriteLine(path + ":" + ex.Message);
}
}
}
}