使用Directory.GetFiles(...)时拒绝访问该路径

时间:2011-02-13 19:20:28

标签: c#

我正在运行下面的代码并在下面获得例外。我是否被迫将此函数放入try catch中,还是以其他方式递归获取所有目录? 我可以编写自己的递归函数来获取文件和目录。但我想知道是否有更好的方法。

// get all files in folder and sub-folders
var d = Directory.GetFiles(@"C:\", "*", SearchOption.AllDirectories);

// get all sub-directories
var dirs = Directory.GetDirectories(@"C:\", "*", SearchOption.AllDirectories);

“拒绝访问路径'C:\ Documents and Settings \'。”

8 个答案:

答案 0 :(得分:34)

如果你想在失败后继续使用下一个文件夹,那么是的;你必须自己做。我建议Stack<T>(深度优先)或Queue<T>(bredth优先)而不是递归,以及迭代器块(yield return);那么你可以避免堆栈溢出和内存使用问题。

示例:

    public static IEnumerable<string> GetFiles(string root, string searchPattern)
    {
        Stack<string> pending = new Stack<string>();
        pending.Push(root);
        while (pending.Count != 0)
        {
            var path = pending.Pop();
            string[] next = null;
            try
            {
                next = Directory.GetFiles(path, searchPattern);                    
            }
            catch { }
            if(next != null && next.Length != 0)
                foreach (var file in next) yield return file;
            try
            {
                next = Directory.GetDirectories(path);
                foreach (var subdir in next) pending.Push(subdir);
            }
            catch { }
        }
    }

答案 1 :(得分:9)

您可以设置程序,以便只能以管理员身份运行。

Visual Studio

Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings

单击它后,将在Project的属性文件夹 app.manifest 下创建一个文件,一旦创建该文件,您可以取消选中Enable ClickOnce Security Settings选项

打开该文件并更改此行:

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

为:

 <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

这将使程序需要管理员权限,并且它将保证您有权访问该文件夹。

答案 2 :(得分:2)

好吧,你要么避开你没有权限的目录,要么你没有权限,但是当访问被拒绝时,你可以优雅地回复。

如果选择第一个选项,则需要确保知道它们是哪个目录,以及线程标识的权限不会更改。这很棘手,容易出错;我不推荐它用于生产质量的系统。

第二种选择看起来更合适。使用try / catch块并跳过任何“禁止”目录。

答案 3 :(得分:0)

我知道这个问题有些陈旧,但今天我遇到了同样的问题,我发现以下文章详细解释了“文件夹递归”解决方案。

文章承认GetDirectories()方法的缺陷......:

  

不幸的是,[[strong> 使用GetDirectories()方法 ]存在问题。其中的关键是一些   您尝试读取的文件夹可以配置为   当前用户可能无法访问它们。而不是忽略文件夹   你有限制访问权限,该方法抛出一个   UnauthorizedAccessException。但是,我们可以绕过这个问题   通过创建我们自己的递归文件夹搜索代码。

...然后详细介绍解决方案:

http://www.blackwasp.co.uk/FolderRecursion.aspx

答案 4 :(得分:0)

已经指出你需要自己做,所以我想我会分享我的解决方案,避免收集。应该注意的是,这将忽略所有错误,而不仅仅是AccessDenied。要改变它,你可以使catch块更具体。

    IEnumerable<string> GetFiles(string folder, string filter, bool recursive)
    {
        string [] found = null;
        try
        {
            found =  Directory.GetFiles(folder, filter);
        }
        catch { }
        if (found!=null)
            foreach (var x in found)
                yield return x;
        if (recursive)
        {
            found = null;
            try
            {
                found = Directory.GetDirectories(folder);
            }
            catch { }
            if (found != null)
                foreach (var x in found)
                    foreach (var y in GetFiles(x, filter, recursive))
                        yield return y;
        }
    }

答案 5 :(得分:0)

此递归方法将返回该文件夹中所有可访问文件的列表。

    static List<string> getFilesInDir(string dirPath)
    {
        List<string> retVal = new List<string>();
        try
        {
            retVal = IO.Directory.GetFiles(dirPath, "*.*", IO.SearchOption.TopDirectoryOnly).ToList();
            foreach (IO.DirectoryInfo d in new IO.DirectoryInfo(dirPath).GetDirectories("*", IO.SearchOption.TopDirectoryOnly))
            {
                retVal.AddRange(getFilesInDir(d.FullName));
            }
        }
        catch (Exception ex)
        {
            //Console.WriteLine(dirPath);
        }
        return retVal;
    }

答案 6 :(得分:0)

您可以通过对第三个参数使用EnumerationOptions来实现此目的。此类提供了一个名为IgnoreInaccessible的属性,该属性可在遇到无法访问的文件/文件夹时切换是否引发异常。

与搜索有关的其他属性也可用,请参见:EnumerationOptions Class (System.IO)


示例:

var options = new EnumerationOptions()
{
    IgnoreInaccessible = true
};

var files = Directory.GetFiles("mypath", "*.*", options);

foreach (var file in files)
{
    // File related activities
}

注意:IgnoreAccessible默认情况下设置为true,但出于可见性考虑,我在上面的示例中将其包括在内。

答案 7 :(得分:-1)

战斗代码示例。不要注意特殊类型。

private void RecursiveDirProcessing(DirectoryInfo dirInfoRoot, ref Dictionary<OfficeType, List<FileInfo>> dict)
    {
        try
        {
            // DO IT! Using dict, we will return the lists
        }
        catch
        {
            AddLog(TypeLog.Error, $"Нет доступа к каталогу {dirInfoRoot.FullName}");
            return;
        }
        foreach (DirectoryInfo dirInfoDirectory in dirInfoRoot.GetDirectories("*", SearchOption.TopDirectoryOnly))
        {
            RecursiveDirProcessing(dirInfoDirectory, ref dict);
        }
    }

RecursiveDirProcessing(dirInfoObj, ref dict);