在目录中搜索特定文件名

本文关键字:文件名 搜索 | 更新日期: 2023-09-27 17:57:15

我正在尝试在系统上的所有卷上搜索特定的文件名,除了系统卷信息或Windows目录,并打印出每个文件的每个完整路径。

我尝试使用Directory.GetFiles,但它只在驱动器 C 内搜索:''或驱动器 D:''(取决于指定的驱动器)

怎样才能实现我的目标?

例如,我想运行程序并搜索名为".DS_Store"的文件(以前使用 mac,现在我的文件系统充满了这些文件......

我真的很感激任何帮助。提前谢谢你

上。程序应以管理员权限执行才能工作

在目录中搜索特定文件名

作为加密锁分析的一部分,我编写了一个定位目标扩展的原型,以下是使用它的方法

var cmd = new LocateTargetFilesCommand();
cmd.Execute()

它将在所有驱动器中搜索两个扩展名:.xlsx.doc。最大的问题是处理权限问题。此外,子文件夹可能具有更广泛的权限,因此,如果您无法访问父文件夹,您仍然可以访问其根目录。

最后,cmd.FoundTargets将包含找到的具有所需扩展名的文件的绝对路径

public class LocateTargetFilesCommand 
{
    private string[] _targetExtensions = new[]
        {
            "xlsx", "doc"
        };
    public LocateTargetFilesCommand()
    {
        FoundTargets = new ConcurrentQueue<string>();
        DirsToSearch = new List<string>();
    }
    public ConcurrentQueue<string> FoundTargets { get; private set; }
    public List<string> DirsToSearch { get; private set; }
    public void Execute()
    {
        DriveInfo[] driveInfos = DriveInfo.GetDrives();
        Console.WriteLine("Start searching");
        foreach (var driveInfo in driveInfos)
        {
            if (!driveInfo.IsReady)
                continue;
            Console.WriteLine("Locating directories for drive: " + driveInfo.RootDirectory);
            GetAllDirs(driveInfo.RootDirectory.ToString());
            Console.WriteLine("Found {0} folders", DirsToSearch.Count);
            foreach (var ext in _targetExtensions)
            {
                Console.WriteLine("Searching for .*" + ext);
                int currentNotificationProgress = 0;
                for (int i = 0; i < DirsToSearch.Count; i++)
                {
                    int progressPercentage = (i * 100) / DirsToSearch.Count;
                    if (progressPercentage != 0)
                    {
                        if (progressPercentage % 10 == 0 && currentNotificationProgress != progressPercentage)
                        {
                            Console.WriteLine("Completed {0}%", progressPercentage);
                            currentNotificationProgress = progressPercentage;
                        }
                    }
                    var dir = DirsToSearch[i];
                    try
                    {
                        string[] files = Directory.GetFiles(dir, "*." + ext, SearchOption.TopDirectoryOnly);
                        foreach (var file in files)
                        {
                            FoundTargets.Enqueue(file);
                        }
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        Console.WriteLine("Skipping directory: {0}", dir);
                        DirsToSearch.Remove(dir);
                    }
                }
                Console.WriteLine("So far located {0} targets", FoundTargets.Count);
            }
            DirsToSearch.Clear();
        }
        Console.WriteLine("Stop searching");
    }
    public void GetAllDirs(string root)
    {
        try
        {
            string[] dirs = Directory.GetDirectories(root);
            DirsToSearch.AddRange(dirs);
            foreach (var dir in dirs)
            {
                GetAllDirs(dir);
            }
        }
        catch (UnauthorizedAccessException)
        {
            //swallow
        }
    }
}

使用 GetLogicalDrives

foreach (var d in Directory.GetLogicalDrives())
{         
     var files = Directory.GetFiles(d, file);         
}

试试这个:

foreach (var drive in Directory.GetLogicalDrives())
{
    foreach (var fileInfo in from dir in Directory.GetDirectories(drive) from file in Directory.GetFiles(dir) select new FileInfo(file))
    {
        // get all details in fileInfo
    }
}

感谢 oleksii,但这是我如何使用这段代码排除所有系统目录的:

public class LocateTargetFilesCommand
{
    private string[] _targetExtensions = new[]
    {
        ".DS_Store"
    };
    public LocateTargetFilesCommand()
    {
        FoundTargets = new ConcurrentQueue<string>();
        DirsToSearch = new List<string>();
    }
    public ConcurrentQueue<string> FoundTargets { get; private set; }
    public List<string> DirsToSearch { get; private set; }
    public void Execute()
    {
        DriveInfo[] driveInfos = DriveInfo.GetDrives();
        Console.WriteLine("Start searching");
        foreach (var driveInfo in driveInfos)
        {
            if (!driveInfo.IsReady)
                continue;
            Console.WriteLine("Locating directories for drive: " + driveInfo.RootDirectory);
            GetAllDirs(driveInfo.RootDirectory.ToString());
            Console.WriteLine("Found {0} folders", DirsToSearch.Count);
            foreach (var ext in _targetExtensions)
            {
                Console.WriteLine("Searching for " + ext);
                int currentNotificationProgress = 0;
                for (int i = 0; i < DirsToSearch.Count; i++)
                {
                    int progressPercentage = (i * 100) / DirsToSearch.Count;
                    if (progressPercentage != 0)
                    {
                        if (progressPercentage % 10 == 0 && currentNotificationProgress != progressPercentage)
                        {
                            Console.WriteLine("Completed {0}%", progressPercentage);
                            currentNotificationProgress = progressPercentage;
                        }
                    }
                    var dir = DirsToSearch[i];
                    try
                    {
                        string[] files = Directory.GetFiles(dir, ext, SearchOption.TopDirectoryOnly);
                        foreach (var file in files)
                        {
                            FoundTargets.Enqueue(file);
                        }
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        Console.WriteLine("Skipping directory: {0}", dir);
                        DirsToSearch.Remove(dir);
                    }
                }
                Console.WriteLine("So far located {0} targets", FoundTargets.Count);
            }
            DirsToSearch.Clear();
        }
        Console.WriteLine("Stop searching");
    }
    public void GetAllDirs(string root)
    {
        try
        {
            string[] dirs = Directory.GetDirectories(root);
            DirsToSearch.AddRange(dirs);
            foreach (var dir in dirs)
            {   
                if(dir.Contains("Windows"))
                    Console.WriteLine("Skipped Windows Directory");
                else if (dir.Contains("Users"))
                    Console.WriteLine("Skipped Users Directory");
                else if (dir.Contains("MSOCache"))
                    Console.WriteLine("Skipped MSOCache Directory");
                else if (dir.Contains("SYSTEM.SAV"))
                    Console.WriteLine("Skipped SYSTEM.SAV Directory");
                else if (dir.Contains("ProgramData"))
                    Console.WriteLine("Skipped ProgramData Directory");
                else if (dir.Contains("System Volume Information"))
                    Console.WriteLine("Skipped System Volume Information Directory");
                else if (dir.Contains("$SysReset"))
                    Console.WriteLine("Skipped $SysReset Directory");
                else
                    GetAllDirs(dir);
            }
        }
        catch (UnauthorizedAccessException)
        {
        }
    }
}