如何在VB.net中枚举目录和子目录
我有一个基本的程序来删除在给定日期创建的文件夹。该程序运行和工作,但它不评估子目录。是否有我做错了或没有考虑的事情 谢谢你的帮助如何在VB.net中枚举目录和子目录,vb.net,visual-studio-2012,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_
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
如果是我,我会编写一个从事件处理程序调用的递归方法。该方法将根目录的路径作为参数。在该方法中,我将循环遍历所提供目录下的子目录,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
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
如bhs所指出,如果您想避免重分析点(也称为连接点)出现问题,您可以包括以下功能:
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
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
然后,您可以在递归方法中使用它来避免这些问题。您也遇到了(或很快就会遇到)我最近遇到的一个问题
如果您试图枚举您在enumerate目录
或enumerate文件夹
上没有权限的文件或文件夹,则方法将简单地停止并引发异常
捕获异常也会导致它停止。这几乎肯定不是你想要的行为
我在这里找到了一个递归解决方案,并在此基础上实现了一个名为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();
}
私有静态IEnumerable FindDeletable文件夹(字符串路径、字符串文件模式、布尔递归)
{
IEnumerable emptyList=新字符串[0];
if(File.Exists(path))
返回新字符串[]{path};
如果(!Directory.Exists(path))
返回空列表;
var top_directory=新目录信息(路径);
//枚举顶部目录中的文件。
var files=top_directory.EnumerateFiles(文件模式).ToList();
var filesLength=files.Count();
var filesList=可枚举
.Range(0,文件长度)
.选择(i=>
{
字符串文件名=null;
尝试
{
var file=files.ElementAt(i);
filename=file.Name;//在此处添加日期检查}
捕获(FileNotFoundException)
{
}
捕获(未经授权的访问例外)
{
}
捕获(无效操作异常)
{
//没有条目了
}
返回文件名;
})
。其中(i=>null!=i);
如果(!递归)
返回文件列表;
var dirs=top_目录。枚举目录(“*”);
var dirsLength=dirs.Count();
var dirsList=可枚举
.范围(0,方向长度)
.SelectMany(i=>
{
字符串dirname=null;
尝试
{
var dir=直接元素(i);
dirname=dir.FullName;
如果(dirname.Length>0)
{
var folderFiles=FindDeletableFolders(dirname,file_pattern,recurse).ToList();
如果(folderFiles.Count==0)
{
尝试
{
Directory.Delete(dirname);
}
抓住
{
}
}
其他的
{
返回文件夹文件;
}
}
}
捕获(未经授权的访问例外)
{
}
捕获(无效操作异常)
{
//没有条目了
}
返回空列表;
});
返回Enumerable.Concat(filesList,dirsList.ToList();
}
我不得不破解一些代码,所以在使用前检查函数并测试它
代码将返回一个可以删除的文件夹列表,并删除它遇到的空文件夹。在您的例程中,您认为它是在哪里“评估子目录”?我假设它是在for循环中使用SearchOption.AllDirectories参数进行评估的。好的,这就是文档针对该搜索选项所说的(名称不正确,IMHO)。因此,如果调试
myRoot.EnumerateDirectory(“*”,SearchOption.AllDirectory)
它会返回一个IEnumerable(目录信息)
,计数只有一个?我应该使用不同的命名方案吗?我的搜索选项不正确,导致不查看子目录吗?非常感谢您抽出时间。