在目录中搜索特定文件名

时间:2014-04-08 13:23:05

标签: c# windows winforms visual-studio-2012 .net-4.5

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

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

我如何实现目标?

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

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

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

4 个答案:

答案 0 :(得分:1)

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

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
        }
    }
}

答案 1 :(得分:0)

使用GetLogicalDrives

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

答案 2 :(得分:0)

试试这个:

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
    }
}

答案 3 :(得分:0)

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

        }
    }
}