我有一个WPF程序,它可以获取某个网络目录中的所有目录,并在listview中列出它们。
问题是目录太多了,加载列表可能需要5秒。
我想知道是否有一种方法可以用更有效的代码来加速这一点。或者甚至是一种将列表存储在数组中的方法,并且在第一次之后每次都查找更改?
For Each i As String In Directory.GetDirectories(dir)
If File.Exists(Path.GetFullPath(i) & "cover.jpg") Then
If (File.GetAttributes(Path.GetFullPath(i)) And FileAttributes.Hidden) <> FileAttributes.Hidden Then
Dim foldername As String = Path.GetFileName(i)
Dim moviename As String = foldername
If moviename.Length > 4 Then
If moviename.Substring(0, 4) = "The " Then
moviename = moviename.Remove(0, 4)
End If
End If
Dim display As Boolean = True
If IO.Directory.GetDirectories(Path.GetFullPath(i)).Length < 1 Then
If IO.Directory.GetFiles(Path.GetFullPath(i), "*.avi").Length < 1 Then
If IO.Directory.GetFiles(Path.GetFullPath(i), "*.mp4").Length < 1 Then
If IO.Directory.GetFiles(Path.GetFullPath(i), "*.mkv").Length < 1 Then
display = False
End If
End If
End If
End If
If display = True Then
Showslist.Items.Add(New With {Key .img = Path.GetFullPath(i) & "cover.jpg", .name = foldername, .path = Path.GetFullPath(i), .created = Directory.GetCreationTime(Path.GetFullPath(i)), .moviename = moviename})
End If
End If
End If
Next
1。不要多次读取目录的内容。相反,一次读取所有需要的内容并将其缓存到一个(内存中的)变量中。这将有助于提高性能,因为访问内存比执行I/O要快得多(这里是访问文件系统)。例如:
If IO.Directory.GetFiles(…, "*.avi").Length < 1 Then If IO.Directory.GetFiles(…, "*.mp4").Length < 1 Then If IO.Directory.GetFiles(…, "*.mkv").Length < 1 Then …
您刚刚查询了同一目录三次。您可以将其更改为只读取一次内容(因此可能会将代码速度提高三次),然后在内存中对其进行过滤:
'Imports System.IO
'Imports System.Linq
' access the file system only once and store the results in-memory…
Dim filePaths As String() = Directory.GetFiles(…, "*")
' … and perform everything else on that in-memory cache:
If Not filePaths.Any(Function(fp) Path.GetExtension(fp) = ".avi") Then
If Not filePaths.Any(…) Then
If Not filePaths.Any(…) Then
…
<子>注::也许值得指出的是,与
Directory.GetFiles
不同,System.IO.Path
方法不应该导致昂贵的文件系统命中:它们只是对已知包含文件系统路径的字符串进行操作。子>
2。考虑递归地读取根目录的完整内容。 Directory.GetFiles
方法有一个过载的Directory.GetFiles(String, String, SearchOption)
, SearchOption
参数可以设置为SearchOption.AllDirectories
。在这种情况下,您不仅可以从指定的目录本身获取内容,还可以从它的所有子目录获取内容。
这意味着,您将需要对Directory.GetFiles
(对于根目录)进行单个调用,而不是多次调用,这意味着您将再次减少昂贵的I/O调用的数量。将结果存储在一个数组中,然后从那里开始构建WPF列表。
' read the contents of the network root directory, including all of its sub-directories…
Dim filePaths As String() = Directory.GetFiles(…, "*", SearchOption.AllDirectories)
' …and do everything else using the in-memory cache built above:
For Each filePath As String in filePaths
…
Showslist.Items.Add(…)
Next