如何在VB.net中枚举目录和子目录

时间:2013-09-25 14:53:17

标签: vb.net visual-studio-2012

我所拥有的是删除在给定日期创建的文件夹的基本程序。该程序运行并运行,但它不是在评估子目录。有什么我做错了或没有考虑。

感谢您的帮助。

Imports System.IO

Public Class FormMain

    Private Sub btn_DeleteFolders_Click(sender As Object, e As EventArgs) Handles btn_DeleteFolders.Click

            Dim myDate As Date = dt_FolderDate.Value.Date
            Dim myRoot As New DirectoryInfo(tb_UNC.Text)

            If tb_UNC.Text Is Nothing Then
                MessageBox.Show("Please select a directory")
            End If

            If Not myRoot.Exists Then
                MessageBox.Show("Directory doesn't exist")
                Exit Sub
            End If


            For Each myDir In myRoot.EnumerateDirectories("*", SearchOption.AllDirectories)
                If myDir.CreationTime.Date = myDate Then
                    myDir.Delete(True)
                End If
            Next
        End If
    End Sub



End Class

2 个答案:

答案 0 :(得分:0)

如果是我,我会写一个我从事件处理程序调用的递归方法。该方法将参数作为根目录的路径。在该方法中,我循环遍历所提供目录下的子目录,并且a。)如果需要,则删除子目录或b。)递归调用子目录上的方法。

这样的事情:

Private Sub Recurse(OnFolderPath As String)
    For Each strSubDir In Directory.GetDirectories(OnFolderPath)
        If (New DirectoryInfo(strSubDir).CreationTime.Date = MyDate) Then
            Directory.Delete(strSubDir)
        Else
            Recurse(strSubDir)
        End If
    Next
End Sub

如果你想避免重新分析点(a.k.a.交接点)的问题,正如bhs指出的那样,你可以包含这样的函数:

Public Function IsJunctionPoint(ByVal ToCheck As DirectoryInfo) As Boolean
    'if the directory has the attributes which indicate that it's a junction point...
    If (((ToCheck.Attributes And FileAttributes.Hidden) = FileAttributes.Hidden) And
        ((ToCheck.Attributes And FileAttributes.System) = FileAttributes.System) And
        ((ToCheck.Attributes And FileAttributes.ReparsePoint) = FileAttributes.ReparsePoint)) Then

        Return True
    Else 'is not a junction point...
        Return False
    End If
End Function

然后你可以在你的递归方法中使用它来避免这些。

答案 1 :(得分:0)

你最近遇到的一个问题也偶然发现了(或者很快就会发生)。

如果您尝试枚举文件或文件夹,但您对EnumerateDirectoriesEnumerateFolders方法没有权限,则只会停止并抛出异常。

捕获异常也会导致异常停止。这几乎肯定不是你想要的行为。

我在这里找到了一个递归解决方案,并在这个SO page上实现了一个名为FindAccessableFiles的方法(我认为它可能是最后一个化身),并且效果非常好。

private static IEnumerable<String> FindDeletableFolders(string path, string file_pattern, bool recurse)
        {
            IEnumerable<String> emptyList = new string[0];

            if (File.Exists(path))
                return new string[] { path };

            if (!Directory.Exists(path))
                return emptyList;

            var top_directory = new DirectoryInfo(path);

            // Enumerate the files just in the top directory.
            var files = top_directory.EnumerateFiles(file_pattern).ToList();
            var filesLength = files.Count();
            var filesList = Enumerable
                      .Range(0, filesLength)
                      .Select(i =>
                      {
                          string filename = null;
                          try
                          {
                              var file = files.ElementAt(i);
                              filename = file.Name; // add your date check here                              }
                          catch (FileNotFoundException)
                          {
                          }
                          catch (UnauthorizedAccessException)
                          {
                          }
                          catch (InvalidOperationException)
                          {
                              // ran out of entries
                          }
                          return filename;
                      })
                      .Where(i => null != i);

            if (!recurse)
                return filesList;

            var dirs = top_directory.EnumerateDirectories("*");
            var dirsLength = dirs.Count();
            var dirsList = Enumerable
                .Range(0, dirsLength)
                .SelectMany(i =>
                {
                    string dirname = null;
                    try
                    {
                        var dir = dirs.ElementAt(i);
                        dirname = dir.FullName;
                        if (dirname.Length > 0)
                        {
                            var folderFiles = FindDeletableFolders(dirname, file_pattern, recurse).ToList();
                            if (folderFiles.Count == 0)
                            {
                                try
                                {
                                        Directory.Delete(dirname);
                                }
                                catch
                                {
                                }
                            }
                            else
                            {
                                return folderFiles;
                            }
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                    }
                    catch (InvalidOperationException)
                    {
                        // ran out of entries
                    }
                    return emptyList;
                });
            return Enumerable.Concat(filesList, dirsList).ToList();
        }

我不得不破解我的一些代码,所以检查功能并在使用前进行测试。

代码将返回可删除的文件夹列表,并删除它遇到的空文件夹。