msdn(https://msdn.microsoft.com/en-us/library/dd383458(v=vs.110).aspx)说:
EnumerateFiles和GetFiles方法的不同之处如下:使用EnumerateFiles时,可以在返回整个集合之前开始枚举名称集合;当您使用GetFiles时,您必须等待返回整个名称数组,然后才能访问该数组。因此,当您使用许多文件和目录时,EnumerateFiles可以更有效。
如何在返回整个集合之前开始使用该集合?
以下代码为大约45000个文件的目录提供了超过3分钟的经过时间
Dim TIme1, TIme2 As String
TIme1 = TimeString
Dim DirFiles As Generic.List(Of String) = New Generic.List(Of String)(Directory.EnumerateFiles(SourceDirectory))
Dim NumberOfFiles As Integer
NumberOfFiles = DirFiles.Count()
TIme2 = TimeString
MsgBox("Begin time " & TIme1 & "There are " & NumberOfFiles & " Photos in the Directory ." & SourceDirectory & "End Time " & TIme2)
在完全阅读完集合之前,我是否可以在Dirfiles中使用条目?怎么样?
在Microsoft推出Windows之前,我曾经是一名专业程序员。我对Windows编程的经验很少。
答案 0 :(得分:2)
虽然您无法充分利用EnumerateFiles
返回的文件数量,但您可以开始使用集合中的单个文件而不会出现For Each
循环等任何不需要的延迟其工作要素的数量。
例如,您可以这样做:
Dim FileCount As Integer
Dim files = Directory.EnumerateFiles(srcDir)
For Each file in files
'Do something with this file
' e.g.
TextBox1.AppendText(file & vbCrLf)
FileCount += 1
Next
MsgBox ( FileCount.ToString & " files processed.")
所以你看看它是如何使用的?
[NB:手绘类型代码..可能包含拼写错误。它只是为了解释这个概念。]
答案 1 :(得分:1)
EnumerateFiles
允许您在找到所有文件之前启动处理文件。您似乎想知道文件的数量。在找到所有文件之前,您无法知道,因此EnumerateFiles
在这种情况下无法为您提供帮助。
答案 2 :(得分:1)
GetFiles
的签名是Directory.GetFiles(path As String) As String()
。为了返回结果,它必须先击中硬盘驱动器并构建整个阵列。如果有45,000个文件,那么它必须构建一个包含45,000个元素的数组才能给你一个结果。
EnumerateFiles
的签名是Directory.EnumerateFiles(path As String) As IEnumerable(Of String)
。在这种情况下,它根本不需要点击硬盘驱动器就能给你一个响应。因此,无论文件数量多少,您都应该能够立即获得结果。
拿这个测试代码:
Dim sw = Stopwatch.StartNew()
Dim files = Directory.GetFiles("C:\Windows\System32")
sw.Stop()
Console.WriteLine(sw.Elapsed.TotalMilliseconds)
我得到大约6.5毫秒的结果来返回文件。
但如果我将GetFiles
更改为EnumerateFiles
,我会在0.07毫秒内得到一个结果。为此文件夹调用GetFiles
要慢近100倍!
这是因为EnumerateFiles
返回IEnumerable<string>
。 IEnumerable(Of T)
的界面是:
Public Interface IEnumerable(Of Out T)
Inherits IEnumerable
Function GetEnumerator() As IEnumerator(Of T)
End Interface
每当我们打电话给foreach
或.Count()
或.ToArray()
时,我们就会调用GetEnumerator()
,而IEnumerator(Of T)
会返回Public Interface IEnumerator(Of Out T)
Inherits IDisposable
Inherits IEnumerator
ReadOnly Property Current As T
Function MoveNext() As Boolean
Sub Reset()
End Interface
类型的另一个对象有这个签名:
MoveNext
这个枚举器实际上做了返回所有文件的艰苦工作。第一次调用Current
后,第一个文件名立即在MoveNext
中可用。然后在循环中调用false
,直到它返回Current
然后您知道循环结束。同时,您可以从EnumerateFiles
属性中收集所有文件。
因此,在您的代码中,如果您对返回的每个文件执行某些操作,那么New Generic.List(Of String)(Directory.EnumerateFiles(SourceDirectory))
将成为可行的方法。
但是因为你正在做EnumerateFiles
,所以你立刻强迫整个可枚举的迭代。使用import json
from json import JSONEncoder
class A:
def __init__ (self, n, a):
self.n = n
self.a = a
class B:
def __init__ (self, b, listOfA):
self.b = b
self.listOfA = []
for a in listOfA:
self.listOfA.append(a)
class AEncoder(JSONEncoder):
def default (self, obj):
if isinstance (obj, A):
return { 'n' : obj.n, 'a' : obj.a }
return json.JSONEncoder.default(self, obj)
class BEncoder(JSONEncoder):
def default (self, obj):
if isinstance (obj, B):
a = AEncoder()
return { 'b' : obj.b, 'listOfA' : [a.default(x) for x in obj.listOfA] }
return json.JSONEncoder.default(self, obj)
listOfA = [A('n1', 'a1'), A('n2', 'a2')]
tmpB = B('b', listOfA)
print(json.dumps(tmpB, cls=BEncoder))
的任何优势都会立即丢失。
答案 3 :(得分:0)
GetFiles方法将实现目录中的整个文件列表。现在调用的首选方法是Directory.EnumerateFiles,因为它会将文件流回(通过类似于类似的机制),因为对OS的底层调用会产生结果。
使用GetFiles / GetDirectories的解决方案有点慢,因为需要创建对象。另一方面,使用枚举不会这样做,它不会创建任何临时对象。
无论哪种方式最终还是迭代发生......
示例文件计数...
Directory.EnumerateFiles(directory, filetype, SearchOption.AllDirectories).Count()
答案 4 :(得分:0)
我现在在enumeratefiles启动之前使用以下内容
Public Function FileCount(PathName As String) As Long
Dim fso As Scripting.FileSystemObject
Dim fld As Scripting.Folder
fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists(PathName) Then
fld = fso.GetFolder(PathName)
FileCount = fld.Files.Count
End If
End Function
这需要Microsoft Scripting Runtime(在项目中设置对VB脚本运行时库的引用)