Chapter 8. Arrays, Files, and Exceptions in VB.Net

VB7 makes some significant changes in the ways you handle arrays and files and completely changes error handling. All of these changes make your programming a lot easier than it was before.

Arrays

In VB7, all arrays are zero based. This is actually the same as in previous versions of Basic, but it was seldom emphasized. In VB6, if you wrote the following

Dim x(10) As Single

then you assumed that the x array had elements from 1 to 10, but it actually always included a zero element as well. In other words, the x array actually had 11 elements. This remains true in VB7.

However, we can also now move through arrays to be in line with the style used in C, C++, C#, and Java.

Dim Max as Integer
Max = 10
Dim x(Max)

For j = 0 to Max-1
 x(j) = j
Next j

However, you can still use

For j = 1 to Max

as you always could.

All array variables have a length property so you can find out how large the array is.

Dim z(20) As Single
Dim j As Integer

For j = 0  To z.Length – 1
       z(j) = j
Next j

But beware! The construction

For j = 0  To z.Length – 1

actually moves through 21 elements. If you declare

Dim z(20) As Single

it contains elements from 0 to 20, or 21 in all. So the value of

z.length

is 21, and moving from 0 to z.length –1 is moving through 21 elements. And, if you were to write

For j = 0  To z.Length

You would pass the upper bound of the array. It is safer to write

For j = 0 to Ubound(z) – 1

Arrays in VB7 are dynamic, and you can reallocate space at any time. To create a reference to an array and allocate it later within the class, use the New syntax.

'Declare at the class level
    Dim x() As Single
'allocate within any method
    x = New Single(20) { }

Note the unusual use of curly braces following the type and size. This means that you are creating a new array object. This syntax applies because you can also specify the contents of the array in the same declaration:

Dim a() As Single
a = New Single() { 1, 3, 4, 5}

You can also use the ReDim statement with or without Preserve to change the size of a declared array. However, you should note that ReDim no longer allows an “As” clause, since the array type cannot be changed during ReDim.

ReDim x(40)
ReDim Preserve x(50)

Collection Objects

The System.Collections namespace contains a number of useful variable-length array objects you can use to add and obtain items in several ways.

ArrayLists

Since arrays are zero-based, VB7 introduces the ArrayList object to replace the Collection object, which was always 1-based. The ArrayList is essentially a variable-length array that you can add items to as needed. The basic ArrayList methods are about the same as for Collections, although there are quite a few more methods you can also use.

Dim i, j As Integer
 'create ArrayList
Dim arl As New ArrayList() 'constructor
 'add to it
 For j = 0 To 9
     Arl.Add(j)
 Next j

Like the Collection object, the ArrayList has a Count property and an Item property that allows you to obtain elements from it by index. And like the Collection, this property can be omitted, treating the ArrayList just as if it were an array.

'print out contents
For i = 0 To arl.Count - 1
    Console.writeLine(arl.Item(i))
    Console.writeLine(arl(i))
Next i

You can also use the methods of the ArrayList shown in Table 8-1.

Hashtables

A Hashtable is a variable-length array where every entry can be referred to by a key value. Typically, keys are strings of some sort, but that can be any sort of object. Keys must be unique for each element, although the elements themselves need not be unique. Hashtables are used to allow rapid access to one of a large and unsorted set of entries and can also be used by reversing the key and the entry values to create a list where each entry is guaranteed to be unique. The most important Hashtable methods are Add and the Item fetch.

Table 8-1. ArrayList Methods

Clear Clears the contents of the ArrayList
Contains(object) Returns true if the ArrayList contains that value
CopyTo(array) Copies entire ArrayList into a one-dimensional array
IndexOf(object) Returns the first index of the value
Insert(index, object) Inserts the element at the specified index
Remove(object) Removes element from list
RemoveAt(index) Removes element from specified position
Sort Sort ArrayList
Dim hash As New Hashtable()
  Dim fredObject As New Object()
  Dim obj As Object
  hash.Add("Fred", fredObject)
  obj = hash.Item("Fred")

Hashtables also have a count property, and you can obtain an enumeration of the keys or of the values.

SortedLists

The SortedList class is most like the VB6 Collection class. It maintains two internal arrays, so you can obtain the elements either by zero-based index or by alphabetic key.

Dim sList As New SortedList()
  slist.Add("Fred", fredObject)
  slist.Add("Sam", obj)
  Dim newObj As Object
  newObj = slist.GetByIndex(0)    'by index
  newObj = slist.Item("Sam")      'by key

You will also find the Stack and Queue objects in this namespace. They behave much as you'd expect, and you can find their methods in the system help documentation.

Exceptions

Error handling in VB7 is accomplished using exceptions instead of the awkward On Error Goto syntax, which is no longer supported. The thrust of exception handling is that you enclose the statements that could cause errors in a Try block and then catch any errors using a Catch statement.

Try
  'Statements
 Catch e as Exception
   'do these if an error occurs
 Finally
   'do these anyway
End Try

Typically, you use this approach to test for errors around file handling statements, although you can also catch array index out-of-range statements and a large number of other error conditions. The way this works is that the statements in the Try block are executed, and if there is no error, control passes to the Finally statements, if any, and then on out of the block. If errors occur, control passes to the Catch statement, where you can handle the errors, and then control passes on to the Finally statements and then on out of the block.

The following example shows testing for any exception. Since we are moving one element beyond the end of the ArrayList, an error will occur.

Try
    For i = 0 To ar.Count               'NOTE: one too many
        Console.write(ar.Item(i))
    Next i
Catch e As Exception
    Console.writeLine(e.Message)
    Console.writeLine(e.stackTrace)
End Try

Console.writeline("end of loop")

This code prints out the error message and the calling locations in the program and then goes on.

0123456789Index is out of range.  Must be non-negative and less
than size.
Parameter name: index
   at System.Collections.ArrayList.get_Item(Int32)
   at ArrayTest.Main()
end of loop

By contrast, if we do not catch the exception, we will get an error message from the runtime system, and the program will exit instead of going on.

Exception occurred: System.ArgumentOutOfRangeException: Index
is out of range.
Must be non-negative and less than size.
Parameter name: index
   at System.Collections.ArrayList.get_Item(Int32)
   at ArrayTest.Main()
   at _vbProject._main(System.String[])

Some of the more common exceptions are shown in Table 8-2.

Table 8-2. VB7 Exceptions

AccessException Error in accessing a method or field of a class
ArgumentException Argument to a method is not valid
ArgumentNullException Argument is null
ArithmeticException Overflow or underflow
DivideByZeroException Division by zero
IndexOutOfRangeException Array index out of range
FileNotFoundException File not found
EndOfStreamException Access beyond end of input stream (such as files)
DirectoryNotFoundException Directory not found
NullReferenceException The object variable has not been initialized to a real value

Multiple Exceptions

You can also catch a series of exceptions and handle them differently in the same Try block.

Try
    For i = 0 To ar.Count
       Dim k As Integer = CType(ar(i), Integer)
       Console.writeLine(i.toString & " " & k / i)
     Next i
Catch e As DivideByZeroException
   Console.writeLine(e.Message)
   Console.writeLine(e.stackTrace)
Catch e As IndexOutOfRangeException
   Console.writeLine(e.Message)
   Console.writeLine(e.stackTrace)
Catch e As Exception
   Console.writeLine("general exception" + e.Message)
   Console.writeLine(e.stackTrace)
End Try

This gives you the opportunity to recover from various errors in different ways.

Throwing Exceptions

You don't have to deal with exceptions exactly where they occur; you can pass them back to the calling program using the Throw statement. This causes the exception to be thrown in the calling program.

Try
  'some code
Catch e as Exception
   Throw e   'pass on to calling routine
End Try

File Handling

You can use some of the file handling functions you are used to in VB6; however, the syntax is rather different because of the requirement that all arguments be enclosed in parentheses. Thus, you will have to make major changes throughout your file handling code.

Input #f, s   'read a string from a file in VB6

becomes

Input(f, s)   'vb6 compatible string read from file

Further, VB7 has no Line Input statement at all. Therefore, it is usually easier to read and write file data using the new File and Stream methods provided in VB7.

The File Object

The File class provides some useful methods for testing for a file's existence as well as renaming and deleting a file. The File object contains only Shared methods. Thus, you call the File class methods without creating an instance. These are all shared methods in VB parlance. Other languages refer to them as static methods, since they work using the class rather than an object. We show some of the most common File methods in Table 8-3. For a complete list, consult the documentation and help files.

Table 8-3. File Methods

Static Method Meaning
File.Exists(filename) True if file exists
File.Delete(filename) Delete the file
File.AppendText(String) Append text
File.getAttributes(String) Return FileAttributes object
File.Copy(fromFile, toFile) Copy a file
File.Move(fromFile, toFile) Move a file, deleting old copy
File.OpenText(filename) Opens text file for reading
File.OpenWrite(filename) Opens any file for reading

For example, if you want to delete a file using the File class you check for its existence and then delete it as follows:

If File.Exists("foo.txt") Then  'test existence
    File.Delete("foo.txt")      'delete it
End If

You can also use the File object to obtain a StreamReader or FileStream for reading and writing file data.

Dim ts As StreamReader
Dim fs As FileStream

ts = File.OpenText("foo.txt")  'open a text file for reading
fs = File.OpenRead("foo.data") 'open any file for reading

Reading a Text File

To read a text file, use the File object to obtain a StreamReader object. Then use the text stream's read methods.

Dim ts As StreamReader
ts = File.OpenText("foo.txt")  'open a text file

Dim s As String
s = ts.ReadLine()

Writing a Text File

To create and write a text file, use the CreateText method to get a StreamWriter object.

Dim sw As StreamWriter
sw = File.CreateText("foo.txt")
sw.WriteLine("Hello there")

If you want to append to an existing file, you can create a StreamWriter object directly with the Boolean argument for append set to true.

'appending
 sw = New StreamWriter("foo.txt", True)

Exceptions in File Handling

A large number of the most common exceptions occur in handling file input and output. You can get exceptions for illegal filenames, files that do not exist, directories that do not exist, illegal filename arguments, and file protection errors. Thus, the best way to handle file input and output is to enclose file manipulation code in Try blocks to assure yourself that all possible error conditions are caught and thus prevent embarrassing fatal errors. All of the methods of the various file classes show in their documentation which methods they throw. You can be sure that you will catch all of them if you catch only the general Exception object, but if you must take different actions for different exceptions, you can test for them separately.

For example, you might open text files in the following manner.

Try
      ts = File.OpenText("foo.txt")
Catch e As FileNotFoundException
     'print out any error
      Console.WriteLine(e.Message)
      errFlag = True
End Try

Testing for End of File

There are two useful ways to make sure that you do not pass the end of a text file: looking for a null exception and looking for the end of a data stream. When you read beyond the end of a file, no error occurs and no end of file exception is thrown. However, if you read a string after the end of a file, it will return as a Null value. VB7 does not provide an IsNull method, but you can easily force a Null Reference exception by trying to obtain the length of a string. If you try to execute a length method on a null string, the system will throw a null reference exception, and you can use this to detect the end of a file.

Public Function readLine() As String
'Read one line from the file
 Dim s As String
 Try
    s = ts.readLine        'read line from file
    lineLength = s.length  'use to catch null exception
 Catch e As Exception
  end_file = True          'set EOF flag if null
  s = ""                   'and return zero length string
 Finally
  readLine = s
 End Try
End Function

The other way for making sure you don't read past the end of a file is to peek ahead, using the Stream's Peek method. This returns the ASCII code for the next character or a –1 if no characters remain.

'example of alternate approach to detecting end of file
 Public Function readLineE() As String
    'Read one line from the file
    Dim s As String
    If ts.peek >= 0 Then      'look ahead
         s = ts.readLine      'read if more chars
         Return s
    Else
         end_file = True      'Set EOF flag if none left
         Return ""
    End If
 End Function

The FileInfo Class

The FileInfo class has all non-shared methods and operates on a particular filename. You can use it to get information about a particular file:

Method Meaning
Attributes Gets FileAttribute object
DirectoryName Gets file's path
Extension Gets the file's extension
Length Length of the file
Name Gets the file's name
Exists True if file exists
Delete() Deletes the file
OpenText() Creates a StreamReader for reading a text file
AppendText() Creates a StreamWriter to append text to file
OpenWrite() Creates a StreamWriter for output

For a complete list consult the documentation.

A vbFile Class

Earlier, we wrote a vbFile class for reading and writing text files a line at a time and a token at a time. We can reimplement this vbFile class for VB7 to have exactly the same methods but utilize the VB7 file handling classes. In essence we are reimplementing the vbFile interface for VB7. Since the syntax remains the same, we might declare formally that we are using the same interface, but since the syntax differs somewhat, we will just write a new class using that same interface.

The main difference is that we can include the filename and path in the constructor. In this example, we use the static File class to obtain the stream reader and writer objects. You can also use an instance of the FileInfo class in a similar fashion. That example is on the CDROM.

Public Sub New(ByVal filename As String)
    'Create new file instance
     File_name = filename     'save file name
     tokLine = ""             'initialize tokenizer
     sep = ","                'and separator
End Sub

We can open a file for reading using either of two methods: one including the filename and one that uses a filename in the argument.

Public Overloads Function OpenForRead() As Boolean
            Return OpenForRead(file_name)
End Function
'----------------
Public Overloads Function OpenForRead(_
ByVal Filename As String) As Boolean
    'opens specified file
    file_name = Filename    'save file name
    errFlag = False         'clear errors
    end_File = False        'and end of file
    Try
        ts = fl.Opentext()    'open the file
    Catch e As Exception
        errDesc = e.Message   'save error message
        errFlag = True        'and flag
    End Try
    Return Not errFlag   'false if error
End Function

You can then read data from the text file as we just illustrated.

Likewise, the following methods allow you to open a file for writing and write lines of text to it.

Public Overloads Function OpenForWrite( _
             ByVal fname As String) As Boolean
     errFlag = False
     Try
         File_name = fname
         sw = File.CreateText(File_name) 'get StreamWriter
      Catch e As Exception
         errDesc = e.Message
         errFlag = True
      End Try
      OpenForWrite = Not errFlag
End Function
'-------------
Public Overloads Function OpenForWrite() As Boolean
    OpenForWrite = OpenForWrite(file_name)
End Function
'-------------
Public Sub writeText(ByVal s As String)
    sw.writeLine(s)              'write text to stream
End Sub

Since we have implemented the same methods in our new vbFile class as for the VB6 class, we can substitute the new one and use it with VB7 programs without changing the surrounding programs at all.

Programs on the CD-ROM

FilesArraysExceptionsArray Showcase use of arrays and ArrayList
FilesArraysExceptionsExceptions Illustrates how to use exceptions
FilesArraysExceptionsFileObject Shows VB7 implementation of the vbFile class using the File object.
FilesArraysExceptionsFileStream Shows VB7 implementation of the vbFile class using the FileInfo object.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset