aa*********@gma il.com wrote:
I think that you're friggin whacked kid.
Erm, that's not exactly the kind of useful response I was hoping for.
But let's roll with it, while I wait for anyone else to answer my
question.
maybe you're trying to store 88,000 items in an array?
Erm, no. That's rather silly.
give us more information; i have a similar project that gave the exact
opposite results... .NET enumerating of folders / files was quite a
bit faster than anything i could do in vb6
VB6 wasn't so great in this department either. That's why I learned to
use the API in the first place.
As currently configured, the test program recursively scans the entire
C: drive, counting files and dirs. It also grabs the size, attribs,
and all three timestamps of each file/dir it encounters and stores them
in a structure which could be used for something productive, but in
this case is promptly discarded. I do it only to make sure the
information is actually read. Two methods are used, the
System.IO.Direc toryInfo, and API calls. I made sure as much as
possible is similar in the two versions, so that the only substantial
time difference is in the .NET/API call.
I also *disregard* the first run, as it suffers a penalty - the
directory info is actually being read from the disk. After that, it's
cached; assuming your memory is big enough and your drive small enough.
By the way, my C: drive has 240,295 files in 16,784 folders. I ran the
test both from the .NET 2.0 IDE and from the Release .exe, and here are
the results:
System.IO.Direc toryInfo, run from IDE: 80,734 ms (milliseconds)
System.IO.Direc toryInfo, Release .exe: 43,671 ms
Windows API, run from IDE: 5,812 ms
Windows API, Release .exe: 4,047 ms
These results are even worse than my initial ones. But at this point,
it doesn't really matter to me *how* ridiculously slow it is - it's
still ridiculously slow. Way more overhead than expected for using the
..NET method (which just calls the API anyway), and unacceptable for a
number of uses I have planned.
I invite you to try this yourself, get your own results, and draw your
own conclusions. And let me know what they are.
Create a new project, add two buttons to a form, delete existing code,
and paste this in (watch out for wordwrap):
-----
Imports System.Runtime. InteropServices
Public Class Form1
Private Const INVALID_HANDLE_ VALUE As Integer = -1
Private Const MAX_PATH As Integer = 260
Structure tFILETIME
Dim dwLowDateTime As Int32
Dim dwHighDateTime As Int32
End Structure
<StructLayout(L ayoutKind.Seque ntial, CharSet:=CharSe t.Ansi)_
Private Structure WIN32_FIND_DATA
Public dwFileAttribute s As Integer
Public ftCreationTime As tFILETIME
Public ftLastAccessTim e As tFILETIME
Public ftLastWriteTime As tFILETIME
Public nFileSizeHigh As UInt32
Public nFileSizeLow As UInt32
Public dwReserved0 As Int32
Public dwReserved1 As Int32
<MarshalAs(Unma nagedType.ByVal TStr, SizeConst:=MAX_ PATH)_
Public cFileName As String
<MarshalAs(Unma nagedType.ByVal TStr, SizeConst:=14)_
Public cAlternateFileN ame As String
End Structure
Private Declare Function FindFirstFile Lib "kernel32" Alias
"FindFirstFileA " (ByVal lpFileName As String, ByRef lpFindFileData As
WIN32_FIND_DATA ) As Int32
Private Declare Function FindNextFile Lib "kernel32" Alias
"FindNextFi leA" (ByVal hFindFile As Int32, ByRef lpFindFileData As
WIN32_FIND_DATA ) As Int32
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As
Int32) As Int32
Public Structure DirItem
Dim Name As String
Dim Size As Long
Dim Attribs As System.IO.FileA ttributes
Dim DateAccessed As Date
Dim DateCreated As Date
Dim DateModified As Date
End Structure
Dim Files, Dirs As Integer
Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button1.Click
Test(1)
End Sub
Private Sub Button2_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button2.Click
Test(2)
End Sub
Sub Test(ByVal Method As Integer)
Dim StartTick As Integer = My.Computer.Clo ck.TickCount
Files = 0
Dirs = 0
Select Case Method
Case 1 : RecurseDirsNet( "c:")
Case 2 : RecurseDirsAPI( "c:")
End Select
MsgBox("Files = " & Files & vbCrLf & "Dirs = " & Dirs & vbCrLf &
"Time (ms)= " & (My.Computer.Cl ock.TickCount - StartTick))
End Sub
Public Sub RecurseDirsAPI( ByVal Path As String)
Dim s1 As String
Dim WFD As New WIN32_FIND_DATA
Dim x As DirItem
Dim hDir As Integer = FindFirstFile(P ath & "\*.*", WFD)
If hDir = INVALID_HANDLE_ VALUE Then Stop
Do
x = New DirItem
s1 = StripNull(WFD.c FileName)
If s1 <"." And s1 <".." Then
With x
.Name = s1
.Size = WFD.nFileSizeLo w + WFD.nFileSizeHi gh * 4294967296
.Attribs = WFD.dwFileAttri butes
.DateAccessed = FileTimeConvert (WFD.ftLastAcce ssTime)
.DateCreated = FileTimeConvert (WFD.ftCreation Time)
.DateModified = FileTimeConvert (WFD.ftLastWrit eTime)
If .Attribs And IO.FileAttribut es.Directory Then
Dirs += 1
RecurseDirsAPI( Path & "\" & .Name)
Else
Files += 1
End If
End With
End If
If FindNextFile(hD ir, WFD) = 0 Then Exit Do
Loop
FindClose(hDir)
End Sub
Public Sub RecurseDirsNet( ByVal Path As String)
Dim x As DirItem
Dim DI As New System.IO.Direc toryInfo(Path & "\")
For Each File As System.IO.FileI nfo In DI.GetFiles
x = New DirItem
With x
.Name = File.Name
.Attribs = File.Attributes
.DateAccessed = File.LastAccess Time
.DateCreated = File.CreationTi me
.DateModified = File.LastWriteT ime
End With
Files += 1
Next
For Each Dir As System.IO.Direc toryInfo In DI.GetDirectori es
x = New DirItem
With x
.Name = Dir.Name
.Attribs = Dir.Attributes
.DateAccessed = Dir.LastAccessT ime
.DateCreated = Dir.CreationTim e
.DateModified = Dir.LastWriteTi me
Dirs += 1
RecurseDirsNet( Path & "\" & .Name)
End With
Next
End Sub
Function StripNull(ByVal X As String) As String
Dim l1 As Long : l1 = InStr(1, X, Chr(0), vbBinaryCompare )
If l1 = 0 Then
StripNull = X
Else
StripNull = Strings.Left(X, l1 - 1)
End If
End Function
Private Function FileTimeConvert (ByVal udtFileTime As tFILETIME) As
Date
FileTimeConvert =
System.DateTime .FromFileTime(u dtFileTime.dwLo wDateTime +
udtFileTime.dwH ighDateTime * 4294967296)
End Function
End Class