在目录中搜索特定文件名

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在目录中搜索特定文件名相关的知识,希望对你有一定的参考价值。

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

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

我怎样才能实现目标?

例如,我想运行程序并搜索名为“.DS_Store”的文件(用于使用mac,现在我的文件系统已经满了这些文件......)

我真的很感激任何帮助。先感谢您

UPD。程序应该使用管理员权限执行

答案

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

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)
        {

        }
    }
}

以上是关于在目录中搜索特定文件名的主要内容,如果未能解决你的问题,请参考以下文章

Javascript,Nodejs:在文件中搜索特定的单词字符串

是否可以在整个设备中搜索特定扩展名的文件?

如何在当前文件夹和所有子文件夹中的所有文件中搜索特定文件内容[重复]

在 FileNet 中搜索特定文件夹的文件夹层次结构

C++ 在文本文件中搜索特定字符串并返回该字符串所在的行号

Erlang - 在外部文件中搜索特定字符串,如果不存在则追加文件