John W. Colby
jcolby at colbyconsulting.com
Fri Mar 14 19:41:00 CST 2003
I thought you folks might be interested in looking at some of the features
that .net exposes. The following is a class directly from "Programming
VB.net" by Francesco Balena. It is fascinating (to me anyway) as it clearly
displays the usage of a whole slew of functionality built in to the .net
environment. It was really an exercise in demonstrating the ability to add
enumerators to any class (where appropriate) so that people using your class
could use "for each" constructs with your classes.
This class iterates a disk path and returns the file name of each file or
directory in turn. Please let's not get in to a "it could have been so much
simpler". I have no idea whether that is true, and really don't much care.
In fact I don't even understand all that is happening here! I am simply
showing the code so that anyone who is interested can see how the author
uses built in classes such as IEnumerator, and the built in stack class of
the Systems.Collection namespace. Seriously cool built in functionality
ready to be built upon.
I built a wrapper function:
Module Module1
Function TestGetEnumerator(ByVal strRoot As String) As String
Dim f As System.IO.FileInfo
Dim str As String
'enumerate all files in strRoot directory tree
For Each f In New FileTree(strRoot)
str = str & f.FullName & vbCrLf
Next
TestGetEnumerator = str
End Function
End Module
Which I then used in the OnOpen event of a form to return a string of all
the files and directories in a given path (hard coded), which I then place
into a text box on a form. What I want to do is have the function be the
datasource for a combo or list but I couldn't figure that out and needed to
move on. ;-)
The result is an EXE which I could mail to you which opens the form and
displays the file names. Of course I can just as easily use the file name
to do some processing on that file, likewise the class could be modified to
return any of the file attributes - size, created date etc.
The EXE is ~10k but of course requires that you have the .net environment on
your computer. Anyone that uses the Windows Update feature to keep their
system up to date with all of the latest patches has probably been offered
the ability to download and install the .net environment needed to run my
10k exe.
Anyway, the class is as follows - all copyrights belong to their owners, not
me.
Public Class FileTree
Implements IEnumerable
'The search Path
Public ReadOnly DirPath As String
'The constructor
Sub New(ByVal DirPath As String)
Me.DirPath = DirPath
End Sub
'Return an enumeraable object(an instance of the inner class)
Function GetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return New FileTreeEnumerator(DirPath)
End Function
'The IEnumerator private object
Class FileTreeEnumerator
Implements IEnumerator
Dim DirPath As String
'This variable contains the Enumerator object for the file list
'in the dir being scanned
Dim FileEnumerator As IEnumerator
'This variable contains the stack of the Enumerator objects
'for subdirs of all pending directories
Dim DirEnumerators As New System.Collections.Stack()
'a simple constructor
Sub New(ByVal DirPath As String)
'Save the dir path
Me.DirPath = DirPath
'manually call the reset method
Reset()
End Sub
Sub Reset() Implements IEnumerator.Reset
'The dir object that represents the root object
Dim di As New System.IO.DirectoryInfo(DirPath)
'get the Enumerator object for the file list, and reset it
FileEnumerator = di.GetFiles.GetEnumerator
FileEnumerator.Reset()
'get the enumerator object for the subdirectory list
Dim dirEnum As IEnumerator = di.GetDirectories.GetEnumerator
dirEnum.Reset()
'push it onto the stack
DirEnumerators.Push(dirEnum)
End Sub
Function MoveNext() As Boolean Implements IEnumerator.MoveNext
'simply delegate to the file enumerator object
If FileEnumerator.MoveNext Then
'it returned true so we can exit
Return True
End If
'if there are no files in the current directory, check
'for another subdirectory in the cuurrent directory
Dim dirEnum As IEnumerator = _
CType(DirEnumerators.Peek, IEnumerator)
'check whether current subdirectory enumerator has more items
Do Until dirEnum.MoveNext
'There are no more subdirectories on this level
'so we must pop another element of the stack
DirEnumerators.Pop()
If DirEnumerators.Count = 0 Then
'return false if no more subdirectories to scan
Return False
End If
'get the current enumerator
dirEnum = CType(DirEnumerators.Peek, IEnumerator)
Loop
'We can create a DirectoryInfo.
Dim di As System.IO.DirectoryInfo = _
CType(dirEnum.Current, System.IO.DirectoryInfo)
'Store the file enumerator and reset it
FileEnumerator = di.GetFiles.GetEnumerator
FileEnumerator.Reset()
'Get the enumerator for the subdir list
'and reset it
dirEnum = di.GetDirectories.GetEnumerator
dirEnum.Reset()
'push it onto the stack
DirEnumerators.Push(dirEnum)
'recursive call to process the file enumerator
Return Me.MoveNext
End Function
'The current property simply delegates to FileEnumerator.Current
ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Return FileEnumerator.Current
End Get
End Property
End Class
End Class
John W. Colby
Colby Consulting
www.ColbyConsulting.com
----------------------------------------------------
Is email taking over your day? Manage your time with eMailBoss.
Try it free! http://www.eMailBoss.com