如何在C#中枚举重新分析点/连接点时检测循环?

时间:2017-07-20 11:40:29

标签: c# .net

我正在使用Directory.EnumerateFiles()来枚举我程序中的文件。我在枚举" 应用数据"时遇到了问题。文件夹(位于: C:\ Program Data \ Application Data )。

EnumerateFiles()进入循环,"应用数据"文件夹还有一个名称为" Application Data"的快捷方式。在它里面还有一个,等等。

经过几次迭代后,路径变得足够长,EnumerateFiles()出现PathTooLongException

如何避免此循环并枚举剩余文件?

代码:

    private void EnumerateRecursively(DirectoryInfo dirInfo, string searchPattern, EnumerationData data)
    {
        try
        {
            EnumerateDirectory(dirInfo, searchPattern, data, SearchOption.TopDirectoryOnly);

            foreach (DirectoryInfo dir in dirInfo.EnumerateDirectories())
                {
                    EnumerateDirectory(dir, searchPattern, data, SearchOption.AllDirectories);
                }
        }
        catch (PathTooLongException ex)
        {
            WriteTrace(FormatExceptionData(ex));
        }
        catch (Exception ex)
        {
            WriteTrace(FormatExceptionData(ex));
        }
    }

private void EnumerateDirectory(DirectoryInfo dir, string searchPattern, EnumerationData data, SearchOption searchOption)
    {
        try
        {
            foreach (FileInfo fileInfo in dir.EnumerateFiles(searchPattern, searchOption))
            {
                //Do something
            }
        }
        catch (PathTooLongException ex)
        {
            WriteTrace(FormatExceptionData(ex));
        }
        catch(UnauthorizedAccessException ex)
        {
            WriteTrace(FormatExceptionData(ex));
        }
        catch (Exception ex)
        {
            WriteTrace(FormatExceptionData(ex));
        }
    }

修改 正如我所知,我在这里称为循环实际上称为重新分析点/连接点。有时这些要点' target具有此重新分析点的副本,在枚举期间会导致无限循环。

2 个答案:

答案 0 :(得分:0)

枚举文件有一个重载,你可以告诉它不要搜索子目录(第三个,searchOption参数):

https://msdn.microsoft.com/en-us/library/dd383571(v=vs.110).aspx

答案 1 :(得分:-2)

我能够在其文件夹/子文件夹中找到任何问题,即使是快捷方式(在子文件夹中的dir1 / dir快捷方式中的dir1快捷方式),这里也是代码。

static void Main(string[] args)
{
    string sourceDirectory = @"C:\dir1";
    string archiveDirectory = @"C:\dir2";

    try
    {
        var txtFiles = Directory.EnumerateFiles(sourceDirectory, "*.txt", SearchOption.AllDirectories);

        foreach (string currentFile in txtFiles)
        {
            string fileName = currentFile.Split("\\".ToCharArray()).Last();
            Directory.Move(currentFile, Path.Combine(archiveDirectory, fileName));
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}