我需要在这个函数中实现文件递归,以获取子目录中的所有文件。
我想保留函数的效率(我的意思是避免在文件夹中使用大循环)
我怎么做?
编辑:我还需要设置一个布尔arg,让我选择是否要启用递归。
' For Each file In Get_Files("C:\Windows", {".dll", ".ini"}) : MsgBox(file.Name) : Next
Private Function Get_Files(ByVal Path As String, ParamArray exts() As String) As List(Of IO.FileInfo)
Return New IO.DirectoryInfo(Path).GetFiles.Where(Function(o) exts.Contains(o.Extension)).ToList
End Function
更新
我需要在dotINSolution修改中保留原始代码的效率,该代码返回IO.FileInfo列表而不是字符串列表:
Private Function Get_Files(ByVal Path As String, ByVal Recursive As Boolean, ParamArray exts() As String) As List(Of String) ' As List(Of IO.FileInfo)
Select Case Recursive
Case True : Return IO.Directory.GetFiles(Path, "*.*", IO.SearchOption.AllDirectories).Where(Function(o) exts.Contains(IO.Path.GetExtension(o))).ToList
Case False : Return IO.Directory.GetFiles(Path, "*.*", IO.SearchOption.TopDirectoryOnly).Where(Function(o) exts.Contains(IO.Path.GetExtension(o))).ToList
End Select
End Function
这可能是没有进行重大更改或者没有多次转换结果吗?
答案 0 :(得分:4)
这应该可以帮到你:)
Private Function Get_Files(ByVal Path As String, ParamArray exts() As String) As List(Of IO.FileInfo)
Return Directory.GetFiles(Path, "*.*", SearchOption.AllDirectories).Where(Function(o) exts.Contains(Path.GetExtension(o))).ToList
End Function
编辑,使用可选的递归:
Private Function Get_Files(ByVal Path As String, Byval searchOption As System.IO.SearchOption, ParamArray exts() As String) As List(Of IO.FileInfo)
Return Directory.GetFiles(Path, "*.*", searchOption).Where(Function(o) exts.Contains(Path.GetExtension(o))).ToList
End Function
仅在热门目录中搜索:
For Each file In Get_Files("C:\Windows", SearchOption.TopDirectoryOnly, {".dll", ".ini"}) : MsgBox(file.Name) : Next
进行递归搜索:
For Each file In Get_Files("C:\Windows", SearchOption.AllDirectories, {".dll", ".ini"}) : MsgBox(file.Name) : Next
答案 1 :(得分:4)
您需要做的就是获取FileInfo而不是文件名的列表,为每个文件创建一个新的FileInfo,如下所示:
Private Function Get_Files(ByVal rootDirectory As String, ByVal recursive As Boolean, ParamArray exts() As String) As List(Of IO.FileInfo)
Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
Return IO.Directory.GetFiles(rootDirectory, "*.*", searchOpt).Where(Function(o) exts.Contains(IO.Path.GetExtension(o))).Select(Function(p) New IO.FileInfo(p)).ToList
End Function
如果您在代码顶部使用Imports System.IO
,则无需输入IO.
这么多,而且看起来更整洁。
编辑:
对于扩展的区分大小写的测试,您可以使用Enumerable.Contains方法实现比较器:
Public Class FilenameExtensionComparer
Implements IEqualityComparer(Of String)
Public Function Equals1(s As String, t As String) As Boolean Implements IEqualityComparer(Of String).Equals
Return String.Compare(s, t, StringComparison.OrdinalIgnoreCase) = 0
End Function
Public Function GetHashCode1(s As String) As Integer Implements IEqualityComparer(Of String).GetHashCode
Return s.GetHashCode()
End Function
End Class
Private Function Get_Files(ByVal rootDirectory As String, ByVal recursive As Boolean, ParamArray exts() As String) As List(Of IO.FileInfo)
Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
Dim filenameExtComparer As New FilenameExtensionComparer
Return IO.Directory.GetFiles(rootDirectory, "*.*", searchOpt).Where(Function(o) exts.Contains(IO.Path.GetExtension(o), filenameExtComparer)).Select(Function(p) New IO.FileInfo(p)).ToList
End Function
我在这个问题中感觉到特征蠕变;)您应该查看所使用的.NET方法的文档,看看它们是否有对您有用的重载。
编辑2:糟糕,我看到你想要不区分大小写。我适当地调整了比较器。答案 2 :(得分:0)
最后,这是我的通用函数,有两个额外的重载来改善函数的使用,这要归功于@Andrew Morton和@dotINSolution修改:
#Region " Get Files "
' [ Get Files Function ]
'
' Examples :
'
' For Each file In Get_Files("C:\Windows", False) : MsgBox(file.Name) : Next
'
' For Each file In Get_Files("C:\Windows", True, "dll") : MsgBox(file.Name) : Next
' For Each file In Get_Files("C:\Windows", True, ".dll") : MsgBox(file.Name) : Next
' For Each file In Get_Files("C:\Windows", True, "*.dll") : MsgBox(file.Name) : Next
'
' For Each file In Get_Files("C:\Windows", False, {"dll", "ini"}) : MsgBox(file.Name) : Next
' For Each file In Get_Files("C:\Windows", False, {".dll", ".ini"}) : MsgBox(file.Name) : Next
' For Each file In Get_Files("C:\Windows", False, {"*.dll", "*.ini"}) : MsgBox(file.Name) : Next
' Get Files {directory} {recursive}
Private Function Get_Files(ByVal directory As String, ByVal recursive As Boolean) As List(Of IO.FileInfo)
Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
Return IO.Directory.GetFiles(directory, "*", searchOpt).Select(Function(p) New IO.FileInfo(p)).ToList
End Function
' Get Files {directory} {recursive} {ext}
Private Function Get_Files(ByVal directory As String, ByVal recursive As Boolean, ext As String) As List(Of IO.FileInfo)
If ext.StartsWith("*") Then
ext = ext.Substring(1, ext.Length - 1)
ElseIf Not ext = "*" AndAlso Not ext.StartsWith(".") Then
ext = ("." & ext)
ElseIf ext = "*" Then
ext = Nothing
End If
Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
Return IO.Directory.GetFiles(directory, "*" & ext, searchOpt).Select(Function(p) New IO.FileInfo(p)).ToList
End Function
' Get Files {directory} {recursive} {exts()}
Private Function Get_Files(ByVal directory As String, ByVal recursive As Boolean, ParamArray exts() As String) As List(Of IO.FileInfo)
Dim FileExtensions(exts.Count) As String
Dim ExtCount As Int64 = 0
For Each ext In exts
If ext.StartsWith("*") Then
FileExtensions(ExtCount) = ext.Substring(1, ext.Length - 1)
ElseIf Not ext = "*" AndAlso Not ext.StartsWith(".") Then
FileExtensions(ExtCount) = ("." & ext)
ElseIf Not ext = "*" AndAlso ext.StartsWith(".") Then
FileExtensions(ExtCount) = ext
ElseIf ext = "*" Then
FileExtensions(ExtCount) = Nothing
End If
ExtCount += 1
Next
Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
Dim filenameExtComparer As New FilenameExtensionComparer
Return IO.Directory.GetFiles(directory, "*.*", searchOpt).Where(Function(o) FileExtensions.Contains(IO.Path.GetExtension(o), filenameExtComparer)).Select(Function(p) New IO.FileInfo(p)).ToList
End Function
' FilenameExtensionComparer
Public Class FilenameExtensionComparer : Implements IEqualityComparer(Of String)
Public Function Equals1(s As String, t As String) As Boolean Implements IEqualityComparer(Of String).Equals
Return String.Compare(s, t, StringComparison.OrdinalIgnoreCase) = 0
End Function
Public Function GetHashCode1(s As String) As Integer Implements IEqualityComparer(Of String).GetHashCode
Return s.GetHashCode()
End Function
End Class
#End Region