figure 2.6
output of listing 2.1.8 when viewed through a browser.
the code in listing 2.1.8 begins by creating three arraylist collections: ateam1, ateam2, and ateam3 (lines 5, 6, and 7, respectively). these three arraylists are then populated with various strings in lines 12 through 22. each of these arraylists is added to the htprojects hashtable on lines 26 through 28. as pointed out earlier, collection types can hold any object, not just simple data types such as integers and strings.
on line 31, an instance of the ienumerator interface is created and assigned to the enumerator for htprojects. (each of the collection types contains a getenumerator() method that returns a read-only enumerator for the collection.) from lines 32 to 34, the enumprojects enumerator is stepped through, visiting each element in the hashtable collection.
note that each element returned to the enumerator from a hashtable is an instance of the dictionaryentry object. the dictionaryentry object contains two public fields: key and value. therefore, on line 33, to obtain the key of the current hashtable element, we need to specify that we want the key field of the current element. we could have created a dictionaryentry instance and referenced the key field in a more explicit manner as follows:
dim dictentry as dictionaryentry
do while enumprojects.movenext()
dictentry = enumprojects.current
lblprojectlisting.text &= dictentry.key & "<br>"
loop
because each entry in htprojects is an arraylist collection itself, we need to create another enumerator to step through each element in each arraylist. this is accomplished on line 37. at the end of our iteration through htprojects in lines 32 through 34, the enumerator enumprojects is positioned at the end of the collection. because we are going to iterate through the htprojects collection again, we need to reposition the enumerator back to before the first element. this is accomplished with the reset method of the ienumerator interface (line 38).
in lines 39 through 48, the htprojects collection is enumerated through again. this time, each element of htprojects is also iterated through itself. on line 42, the enumteam enumerator is assigned via the getenumerator() method of the current arraylist collection. next, the enumteam enumerator is stepped through in lines 43 through 45, outputting each arraylist element (line 44).
conclusion
the .net framework provides developers with a number of powerful collection-type classes, greatly extending the functionality of the scripting.dictionary object, the sole collection type available for classic asp developers. these collections, although each have unique capabilities, are more alike than they are different. all of them share similar methods and properties, and can have their elements iterated through using a number of techniques.
--------------------------------------------------------------------------------
note
all of the collection types we've examined in this chapter inherit from the icollection interface. this interface is responsible for providing the size, enumeration, and synchronization methods for collection types. all of the classes in the .net framework that inherit the icollection interface support the basic collection functionality discussed in this section, "similarities among the collection types."
--------------------------------------------------------------------------------
2. working with the file system
very often web application developers need to have the ability to access the file system on the web server. perhaps they need to list the contents of a particular text file, remove a temporary directory or file, or copy a file from one location to another.
classic asp provided adequate support for working with the web server's file system. the filesystemobject object—along with its accompanying objects such as the file, folder, and textstream objects—permitted the classic asp developer to perform rudimentary tasks with the web server's file system. one serious shortcoming of the filesystemobject was that the developer, without having to jump through hoops, could only read and write text files; reading and writing binary files with the filesystemobject was possible, but a pain.
the .net framework provides a number of classes for working with the file system. these classes are much more robust and have greater functionality than their filesystemobject counterparts. in this section, we'll look at how to accomplish some common file system tasks:
reading, creating, and deleting directories
reading, writing, and creating files
reading, creating, and deleting directories
in classic asp, developers could access directory information with the folder object, one of the many useful filesystemobject objects. the .net framework provides a plethora of file system–accessing classes in the system.io namespace, including a directoryinfo class. this class will be examined in this section.
listing 2.2.1 illustrates the directoryinfo class in action! from listing2.2.1.aspx, the user can enter the name of a directory on the web server. the page will then list the properties of that directory (if it exists), along with the directory's subdirectories. the output is shown in figure 2.7.
listing 2.2.1 the directoryinfo class provides information about a particular directory
1: <%@ import namespace="system.io" %>
2: <script language="vb" runat="server">
3: sub page_load(sender as object, e as eventargs)
4: if not page.ispostback then
5: lbldirinfo.text = "enter the fully qualified name of the " & _
6: "directory that you're interested in (<i>i.e., c:/</i>)"
7: else
8: ' a postback, so get the directory information
9: dim dirinfo as directoryinfo = new
directoryinfo(txtdirectoryname.text)
10:
11: try
12: ' display the directory properties
13: lbldirinfo.text = "<b>information for " & txtdirectoryname.text & _
14: "</b><br> attributes: " & _
15: displayattributes(dirinfo.attributes) & "<br>creation time:" & _
16: dirinfo.creationtime.toshortdatestring() & _
17: ", " & dirinfo.creationtime.tolongtimestring() & _
18: "<br>full name: " & dirinfo.fullname & "<br>" & _
19: "root drive: " & dirinfo.root.name & "<br>" & _
20: "parent directory name: " & dirinfo.parent.name & "<br>" & _
21: "directory name: " & dirinfo.name & "<br>last access time: " & _
22: dirinfo.lastaccesstime.toshortdatestring() & ", " & _
23: dirinfo.lastaccesstime.tolongtimestring() & "<br>" & _
24: "last write time: " & dirinfo.lastwritetime.toshortdatestring() & _
25: ", " & dirinfo.lastwritetime.tolongtimestring() & "<br>"
26:
27: ' list all of the subdirectories for the current directory:
28: lblsubdirectories.text = "<b>subdirectories of " & _
29: dirinfo.fullname & "</b><br>"
30: dim dirsubdirectory as directoryinfo
31: for each dirsubdirectory in dirinfo.getdirectories()
32: lblsubdirectories.text &= dirsubdirectory.fullname & "<br>"
33: next
34: catch dnfexception as directorynotfoundexception
35: ' whoops! a directorynotfound exception has been raised!
36: ' the user entered an invalid directory name!
37: lbldirinfo.text = "<font color=red><b>" & _
38: dnfexception.message & "</b></font>"
39: end try
40: end if
41: end sub
42:
43:
44: function displayattributes(fsa as fileattributes) as string
45: 'display the file attributes
46: dim stroutput as string = ""
47:
48: if (fsa bitand fileattributes.archive) > 0 then
stroutput &= "archived, "
49: if (fsa bitand fileattributes.compressed) > 0 then
stroutput &= "compressed, "
50: if (fsa bitand fileattributes.directory) > 0 then
stroutput &= "directory, "
51: if (fsa bitand fileattributes.encrypted) > 0 then
stroutput &= "encrypted, "
52: if (fsa bitand fileattributes.hidden) > 0 then
stroutput &= "hidden, "
53: if (fsa bitand fileattributes.normal) > 0 then
stroutput &= "normal, "
54: if (fsa bitand fileattributes.notcontentindexed) > 0 then _
55: stroutput &= "not content indexed, "
56: if (fsa bitand fileattributes.offline) > 0 then
stroutput &= "offline, "
57: if (fsa bitand fileattributes.readonly) > 0 then
stroutput &= "read only, "
58: if (fsa bitand fileattributes.reparsepoint) > 0 then
stroutput &= "reparse point, "
59: if (fsa bitand fileattributes.sparsefile) > 0 then
stroutput &= "sparse file, "
60: if (fsa bitand fileattributes.system) > 0 then
stroutput &= "system, "
61: if (fsa bitand fileattributes.temporary) > 0 then
stroutput &= "temporary, "
62:
63: ' whack off the trailing ", "
64: if stroutput.length > 0 then
65: displayattributes = stroutput.substring(0, stroutput.length - 2)
66: else
67: displayattributes = "no attributes found..."
68: end if
69: end function
70: </script>
71:
72: <html>
73: <body>
74: <form method="post" runat="server">
75: <b>get information on directory:</b><br>
76: <asp:textbox runat="server" id="txtdirectoryname" /><p>
77: <asp:button id="btnsubmit" runat="server" type="submit" text="go!" />
78: <p><hr><p>
79: <asp:label runat="server" id="lbldirinfo" /><p>
80: <asp:label runat="server" id="lblsubdirectories" />
81: </form>
82: </body>
83: </html>