Home

Introduction to File Processing

 

Overview of File Processing and Definitions

 

Introduction

A piece of information used in an application is primarily represented as a group of bits. So far, if we requested information from the user, when the application exited, we lost all information that the user had entered. This is because such information was only temporarily stored in the random access memory (RAM). In some cases, you will want to "keep" information that the user has entered so you can make the information available the next time the user opens the application. In some other cases, whether you request information from the user or inherently provide it to the user, you may want different people working from different computers to use or share the same data. In these and other scenarios, you must store the information somewhere and retrieve it when necessary. This is the basis of file processing.

Files

A file is a series of bytes of data that are arranged in a particular manner to produce a usable document. For easy storage, location, and management, the bytes are stored on a medium such as a hard disc, a floppy disc, a compact disc, or any valid and supported type of storage. When these bytes belong to a single but common entity and hold values that are stored on a medium, the group is referred to as a file.

For greater management, files can be stored in a parent object called a directory or a folder. Since a file is a unit of storage and it stores information, it has a size, which is the number of bits it uses to store its values. To manage it, a file has a location also called a path that specifies where and/or how the file can be retrieved. Also, for better management, a file has attributes (characteristics) that indicate what can be done on the file or that provide specific information that the programmer or the operating system can use when dealing with the file.

Streams

File processing consists of creating, storing, and/or retrieving the contents of a file from a recognizable medium. For example, it is used to save word-processed files to a hard drive, to store a presentation on floppy disk, or to open a file from a CD-ROM. A stream is the technique or means of performing file processing. In order to manage files stored in a computer, each file must be able to provide basic pieces of information about itself. This basic information is specified when the file is created but can change during the lifetime of a file.

To create a file, a user must first decide where it would be located: this is a requirement. A file can be located on the root drive. Alternatively, a file can be positioned inside of an existing folder. Based on security settings, a user may not be able to create a file just anywhere in the (file system of the) computer. Once the user has decided where the file would reside, there are various means of creating files that the users are trained to use. When creating a file, the user must give it a name following the rules of the operating system combined with those of the file system. The most fundamental piece of information a file must have is a name.

Once the user has created a file, whether the file is empty or not, the operating system assigns basic pieces of information to it. Once a file is created, it can be opened, updated, modified, renamed, etc.

Streaming Prerequisites

 

Introduction

To support file processing, the .NET Framework provides the System.IO namespace that contains many different classes to handle almost any type of file operation you may need to perform. Therefore, to perform file processing, you can include the System.IO namespace in your project.

The parent class of file processing is Stream. With Stream, you can store data to a stream or you can retrieve data from a stream. Stream is an abstract class, which means you cannot use it to declare a variable in your application. As an abstract class, Stream is used as the parent of the classes that actually implement the necessary operations. You will usually use a combination of classes to perform a typical operation. For example, some classes are used to create a stream object while some others are used to write data to the created stream.

Practical LearningPractical Learning: Introducing Streaming

  1. Start Microsoft Visual Basic or Visual Studio and create a Windows Application named ClarksvilleIceCream2
  2. In the Solution Explorer, right-click Form1.vb and click Rename
  3. Type Exercise.vb and press Enter twice
  4. In the Properties window, change the form's Text to Ice Cream Vending Machine
  5. Design the form as follows:
     
    Ice Cream Vending Machine
    Control Name Text Additional Properties
    GroupBox      
    Label   Order Date:  
    DateTimePicker dtpOrderDate   Format: Short
    Label   Order Time:  
    DateTimePicker dtpOrderTime   Format: Time
    ShowUpDown: True
    Label   Flavor:  
    ComboBox cboFlavors   DropDownStyle: DropDownList
    Label   Container:  
    ComboBox cboContainers   DropDownStyle: DropDownList
    Label   Ingredient:  
    ComboBox cboIngredients   DropDownStyle: DropDownList
    Label   Scoops:  
    TextBox txtScoops 1 TextAlign: Right
    Label   Order Total:  
    TextBox txtOrderTotal 0.00 TextAlign: Right
    Button btnClose Close Click to end
  6. Click the combo box to the right of the Flavor label. Then, in the Properties, click the ellipsis button Ellipsis of Items property and create the list with:
     
    Vanilla
    Cream of Cocoa
    Chocolate Chip
    Cherry Coke
    Butter Pecan
    Chocolate Cookie
    Chunky Butter
    Organic Strawberry
    Chocolate Brownies
    Caramel Au Lait
  7. Click OK
  8. Click the combo box to the right of the Container label. Then, in the Properties, click the ellipsis button Ellipsis of Items property and create the list with:
     
    Cone
    Cup
    Bowl
  9. Click OK
  10. Click the combo box to the right of the Ingredient label. Then, in the Properties, click the ellipsis button Ellipsis of Items property and create the list with:
     
    None
    Peanuts
    Mixed Nuts
    M & M
    Cookies
  11. Click OK
  12. Right-click the form and click View Code
  13. In the Class Name combo box, select txtScoops
  14. In the Method Name combo box, select Leave and implement the event as follows:
     
    Private Sub txtScoops_Leave(ByVal sender As Object, _
                                    ByVal e As System.EventArgs) _
                                    Handles txtScoops.Leave
            Dim PriceContainer As Double
            Dim PriceIngredient As Double
            Dim PriceScoops As Double
            Dim OrderTotal As Double
            Dim NumberOfScoops As Integer = 1
    
            ' The price of a container depends on which one the customer selected
            If cboContainers.Text = "Cone" Then
                PriceContainer = 0.55
            ElseIf cboContainers.Text = "Cup" Then
                PriceContainer = 0.75
            Else
                PriceContainer = 1.15
            End If
    
            ' Find out if the customer wants any ingredient at all
            If cboIngredients.Text = "None" Then
                PriceIngredient = 0.0
            Else
                PriceIngredient = 0.95
            End If
    
            Try
                ' Get the number of scoops
                NumberOfScoops = CInt(txtScoops.Text)
    
                If NumberOfScoops = 1 Then
                    PriceScoops = 1.85
                ElseIf (NumberOfScoops = 2) Then
                    PriceScoops = 2.55
                Else ' if( NumberOfScoops= 3 )
                    PriceScoops = 3.25
                End If
    
                ' Make sure the user selected a flavor, 
                ' otherwise, there is no reason to process an order
                If cboFlavors.Text <> "" Then
                    OrderTotal = PriceScoops + PriceContainer + PriceIngredient
                    txtOrderTotal.Text = OrderTotal.ToString("F")
                End If
            Catch ex As Exception
                MsgBox("The value you entered for the scoops is not valid" & _
                                 vbCrLf & "Only natural numbers such as 1," & _
                                 vbCrLf & " 2, or 3 are allowed" & _
                                 vbCrLf & "Please try again")
            End Try
    End Sub
  15. Execute the application. Here is an example:
     
    Clarksville Ice Cream
  16. Close the form and return to Visual Studio

The Name of a File

Before performing file processing, one of your early decisions will consist of specifying the type of operation you want the user to perform. For example, the user may want to create a brand new file, open an existing file, or perform a routine operation on a file. In all or most cases, whether you are creating a new file or manipulating an existing one, you must specify the name of the file. You can do this by declaring a String variable but, as we will learn later on, most classes used to create a stream can take a string that represents the file.

If you are creating a new file, there are certainly some rules you must observe. The name of a file follows the directives of the operating system. On MS DOS and Windows 3.X (that is, prior to Microsoft Windows 9X), the file had to use the 8.3 format. The actual name had to have a maximum of 8 characters with restrictions on the characters that could be used. The user also had to specify three characters after a period. The three characters, known as the file extension, were used by the operating system to classify the file. That was all necessary for those 8-bit and 16-bit operating systems. Various rules have changed. For example, the names of folders and files on Microsoft Windows >= 95 can have up to 255 characters. The extension of the file is mostly left to the judgment of the programmer but the files are still using extensions. Applications can also be configured to save different types of files; that is, files with different extensions.

Author Note At the time of this writing, the rules for file names for Microsoft Windows were on the MSDN web site at Windows Development\Windows Base Services\Files and I/O\SDK Documentation\Storage\Storage Overview\File Management\Creating, Deleting, and Maintaining Files\Naming a File (because it is a web site and not a book, its pages can change anytime).

Based on this, if you declare a String variable to hold the name of the file, you can simply initialize the variable with the necessary name and its extension. Here is an example:

Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Employees.spr"
End Sub 

Practical LearningPractical Learning: Specifying the Name of a File

  1. Right-click the form and click View Code
  2. Just above the Public Class line, import the System.IO namespace:
     
    Imports System.IO
    
    Public Class Exercise
  3. In the Class Name combo box, select btnClose
  4. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnClose_Click(ByVal sender As Object, _
                                   ByVal e As System.EventArgs) _
                                   Handles btnClose.Click
            Dim answer As MsgBoxResult = _
                MsgBox("Do you want to save this order to remember it " & _
                                "the next time you come to " & _
                                         "get your ice scream?", _
                       MsgBoxStyle.YesNo Or MsgBoxStyle.Question, _
                       "Ice Cream Vending Machine")
    
            If answer = MsgBoxResult.Yes Then
                Dim Filename As String = InputBox( _
                    "Please type your initials and press Enter", _
                    "Ice Cream Vending Machine", "AA", 100, 100)
                If Filename <> "" Then
                    ' Wonderful
                Else
                    MsgBox("The ice cream order will not be saved")
                End If
            End If
    
            MsgBox("Good Bye: It was a delight serving you")
            Close()
    End Sub
  5. Scroll up in the file and, under the other using lines, type Imports System.IO

The Path to a File

If you declare a string as above, the file will be created in the folder as the application. Otherwise, you can create your new file anywhere in the hard drive. To do that, you must provide a complete path where the file will reside. A path is a string that specifies the drive (such as A:, C:, or D:). The sections of a complete path string are separated by a backslash. For example, a path can the made of a folder followed by the name of the file. An example would be

C:\Palermo.tde 

A path can also consist of a drive followed by the name of the folder in which the file will be created. Here is an example:

C:\Program Files\Palermo.tde

A path can also indicate that the file will be created in a folder that itself is inside of another folder. In this case, remember that the names of folder must be separated by backslashes.

When providing a path to the file, you could encounter different types of problems:

  • If the drive you specify does not exist or cannot be read, the compiler would consider that the file does not exist
  • If you provide folders that do not exist in the drive, the compiler would consider that the file does not exist. This also means that the compiler will not create the folder(s) (the .NET Framework provides all means to create a folder but you must ask the compiler to create it; simply specifying a folder that does not exist will not automatically create it, even if you are creating a new file).

Therefore, it is your responsibility to make sure that either the file or the path to the file is valid. As we will see in the next sections, the compiler can check the existence of a file or path.

The .NET Support for Files

 

Introduction

The primary support of a file as an object is provided by a .NET Framework class called File. This Shared class is equipped with various types of (static) methods to create, save, open, copy, move, delete, or check the existence of a file. As an alternative, the Microsoft Visual Basic library provides the My object that includes the FileSystem object in the Computer object.

File Existence

One of the valuable operations that the File class can perform is to check the existence of the file you want to use. For example, if you are creating a new file, you may want to make sure it does not exist already because if you try to create a file that exists already, the compiler may first delete the old file before creating the new one. This could lead to unpredictable results, especially because such a file is not sent to the Recycle Bin. On the other hand, if you are trying to open a file, you should first make sure the file exists, otherwise the compiler will not be able to open a file it cannot find.

To check the existence of a file, the File class provides the Exists method. Its syntax is:

Public Shared Function Exists(path As String) As Boolean

To perform this operation using the FileSystem class from My, you can call its FileExists() method whose syntax is:

Public Function FileExists(ByVal file As String) As Boolean

If you provide only the name of the file, the compiler would check it in the folder of the application. If you provide the path to the file, the compiler would check its drive, its folder(s) and the file itself. In both cases, if the file exists, the method returns True. If the compiler cannot find the file, the method returns False. It is important to know that if you provide a complete path to the file, any slight mistake would produce a False result.

File Creation

Besides checking the existence of the file, the File class can be used to create a new file. To support this operation, the File class is equipped with the Create() method that is overloaded with two versions as follows:

Public Shared Function Create(path As String) As FileStream
Public Shared Function Create(path As String, bufferSize As Integer) As FileStream

In both cases, the File.Create() method returns a Stream value, which is a FileStream value. As the File.Create() method indicates, it takes the name or path of the file as argument. If you know or want to specify the size, in bytes, of the file, you can use the second version.

To provide the same operation of creating a file, you can use the Open() method of the File class. It is overloaded in three versions as follows:

Public Shared Function Open ( _
	path As String, _
	mode As FileMode _
) As FileStream

Public Shared Function Open ( _
	path As String, _
	mode As FileMode, _
	access As FileAccess _
) As FileStream
Public Shared Function Open ( _
	path As String, _
	mode As FileMode, _
	access As FileAccess, _
	share As FileShare _
) As FileStream

Access to a File

In order to perform an operation on a file, you must specify to the operating system how to proceed. One of the options you have is to indicate the type of access that will be granted on the file. This access is specified using the FileAccess enumerator. The members of the FileAccess enumerator are:

  • FileAccess.Write: New data can be written to the file
  • FileAccess.Read: Existing data can be read from the file
  • FileAccess.ReadWrite: Existing data can be read from the file and new data be written to the file

File Sharing

In standalone workstations, one person is usually able to access and open a file then perform the necessary operations on it. In networked computers, you may create a file that different people can access at the same time or you may make one file access another file to retrieve information. For example, suppose you create an application for a fast food restaurant that has two or more connected workstations and all workstations save their customers orders to a common file. In this case, you must make sure that any of the computers can access the file to save an order. An employee from one of these workstations must also be able to open the file to retrieve a customer order for any necessary reason. You can also create a situation where one file holds an inventory of the items of a store and another file holds the customers orders. Obviously one file would depend on another. Based on this, when an operation must be performed on a file, you may have to specify how a file can be shared. This is done through the FileShare enumerator.

The values of the FileShare enumerator are:

  • FileShare.Inheritable: Allows other file handles to inherit from this file
  • FileShare.None: The file cannot be shared
  • FileShare.Read: The file can be opened and read from
  • FileShare.Write: The file can be opened and written to
  • FileShare.ReadWrite: The file can be opened to write to it or read from it

The Mode of a File

Besides the access to the file, another option you will most likely specify to the operating system is referred to as the mode of a file. It is specified through the FileMode enumerator. The members of the FileMode Enumerator are:

  • FileMode.Append: If the file already exists, the new data will be added to its end. If the file doesn't exist, it will be created and the new data will be added to it
  • FileMode.Create: If the file already exists, it will be deleted and a new file with the same name will be created. If the file doesn't exist, then it will be created
  • FileMode.CreateNew: If the new already exists, the compiler will throw an error. If the file doesn't exist, it will be created
  • FileMode.Open: If the file exists, it will be opened. If the file doesn't exist, an error would be thrown
  • FileMode.OpenOrCreate: If the file already exists, it will be opened. If the file doesn't exist, it will be created
  • FileMode.Truncate: If the file already exists, its contents will be deleted completely but the file will be kept, allowing you to write new data to it. If the file doesn't exist, an error would be thrown

Starting and Closing a Stream

 

Starting a Stream

File streaming consists of performing one of the routine operations on a file, such as creating or opening it. This basic operation can be performed using a class called FileStream. You can use a FileStream object to get a stream ready for processing. As one of the most complete classes of file processing of the .NET Framework, FileStream is equipped with all necessary properties and methods. To use it, you must first declare a variable of it. The class is equipped with nine constructors.

One of the constructors of the FileStream class has the following syntax:

Public Sub New(path As String, mode As FileMode)

This constructor takes as its first argument the name of the file or its path. The second argument specifies the type of operation to perform on the file. Here is an example of calling this method:

Imports System.IO

Public Class Exercise

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Persons.prs"

        Dim StreamPersons As FileStream = New FileStream(Filename, FileMode.Create)
   
    End Sub
End Class

Closing a Stream

When you use a stream, it requests resources from the operating system and uses them while the stream is available. When you are not using the stream anymore, you should free the resources and make them available again to the operating system so that other services can use them. This is done by closing the stream.

To close a stream, you can can call the Close() method of the class(es) you were using. Here are examples:

Public Class Exercise

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Persons.prs"

        Dim StreamPersons As FileStream = New FileStream(Filename, FileMode.Create)
   
        StreamPersons.Close()
    End Sub
End Class

Stream Writing

 

Binary Writing

A streaming operation is typically used to create a stream. Once the stream is ready, you can write data to it. The writing operation is performed through various classes. One of these classes is called BinaryWriter.

The BinaryWriter class can be used to write values of primitive data types (char, int, float, double, etc). To use a BinaryWriter value, you can first declare its variable. To do this, you would use one of the class' three constructors. The first constructor is the default. The second constructor has the following syntax:

Public Sub New(output As Stream)

This constructor takes as argument a Stream value, which could be a FileStream variable. Here is an example:

Public Class Exercise

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Persons.prs"

        Dim StreamPersons As FileStream = New FileStream(Filename, FileMode.Create)
        Dim WriterPersons As BinaryWriter  = new BinaryWriter(fstPersons)
   
    End Sub
End Class

As mentioned already, make sure you close a stream after using it. In the same way, make sure you close a writer after using it. If you are using both, you should close them in the reverse order they were used.

Most classes that are used to add values to a stream are equipped with a method called Write. This is also the case for the BinaryWriter class. This method takes as argument the value that must be written to the stream. The method is overloaded so that there is a version for each primitive data type. Here is an example that adds strings to a newly created file:

Persons

Imports System.IO

Public Class Exercise

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Persons.prs"

        Dim PersonsStream As FileStream
        Dim PersonsWriter As BinaryWriter

        PersonsStream = New FileStream(Filename, FileMode.Create)
        PersonsWriter = New BinaryWriter(PersonsStream)

        PersonsWriter.Write(txtPerson1.Text)
        PersonsWriter.Write(txtPerson2.Text)
        PersonsWriter.Write(txtPerson3.Text)
        PersonsWriter.Write(txtPerson4.Text)

        PersonsWriter.Close()
        PersonsStream.Close()

        txtPerson1.Text = ""
        txtPerson2.Text = ""
        txtPerson3.Text = ""
        txtPerson4.Text = ""
    End Sub
End Class

Stream Writing

As mentioned already, the BinaryWriter class considers the values it has to write as binary values in the orders of integers, characters, and their variants. In some cases, you may want to write a block of text. To support this, the .NET Framework provides the StreamWriter class. StreamWriter is derived from the TextWriter class, which the base class used to write a series of characters to a stream. To assist you with writing operations, the StramWriter class is equipped with various constructors.

If you had previously defined a FileStream object and you want to write values to it, you can use the following constructor of the StreamWriter class to create a stream:

Public Sub New (stream As Stream)

This method takes as argument a Stream-based variable, which could be a FileStream value. Here is an example of using it:

Imports System.IO

Public Class StudentRegistration

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Student.std"

        Dim StudentsStreamer As FileStream
        Dim StudentsWriter As StreamWriter

        StudentsStreamer = New FileStream(Filename, FileMode.Create)
        StudentsWriter = New StreamWriter(StudentsStreamer)
    End Sub
End Class

If you do not want to use a Stream-based class, you can directly provide a file to the StreamWriter. To support this, the class is equipped with the following constructor:

Public Sub New(path As String)

This method takes as argument the name of, or a path to, a file.

After creating a StreamWriter object, you can write one or more values to it. To support this, the TextWriter class is equipped with the Write() method that the StreamWriter class inherits. The StreamWriter class itself is equipped is equipped with w method named WriteLine that is given in various versions, each version adapted to a particular data type. The Write() method writes text on a line and keeps the caret on the same line. The WriteLine() method writes a line of text and moves the caret to the next line.

Here is an example of using a StreamWriter class to write values to a file:

After creating a StreamWriter object, you can write one or more values to it. To support this, the TextWriter class is equipped with the Write() method that the StreamWriter class inherits. The StreamWriter class itself is equipped is equipped with w method named WriteLine that is given in various versions, each version adapted to a particular data type.

Imports System.IO

Public Class StudentRegistration

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Student.std"

        Dim StudentsStreamer As FileStream
        Dim StudentsWriter As StreamWriter

        StudentsStreamer = New FileStream(Filename, FileMode.Create)
        StudentsWriter = New StreamWriter(StudentsStreamer)

        StudentsWriter.WriteLine(txtFirstName.Text)
        StudentsWriter.WriteLine(txtLastName.Text)
        StudentsWriter.WriteLine(cbxGenders.SelectedIndex)

        StudentsWriter.Close()
        StudentsStreamer.Close()

        txtFirstName.Text = ""
        txtLastName.Text = ""
        cbxGenders.SelectedIndex = 2
    End Sub
End Class

Using My File System

By default, the FileStream class does not specify what operation is going to be performed on the file. If you are planning to create a new file and write values to it, you can call the OpenTextFileWriter() method of the FileSystem class of the My object. It comes in two versions whose syntaxes are:

Public Function OpenTextFileWriter( _
   ByVal file As String, _
   ByVal append As Boolean _
) As System.IO.StreamWriter

Public Function OpenTextFileWriter( _
   ByVal file As String, _
   ByVal append As Boolean, _
   ByVal encoding As System.Text.Encoding _
) As System.IO.StreamWriter

The first argument is the name of, or the path to, the file that will receive the new values. The second argument specifies whether this is a new file or you are opening it to add new values to it. If this is a new file, pass the append argument as False. The encoding argument allows you to specify the type of text that you want to use.

This method returns a StreamWriter. Here is an example of creating a stream writer by calling the OpenTextFileWriter() method:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, _
			ByVal e As System.EventArgs) _
			Handles Button1.Click
        Dim fstPeople As StreamWriter

        fstPeople = My.Computer.FileSystem.OpenTextFileWriter("People1.ppl", False)

    End Sub
End Class

After creating the stream writer, you can then write values to it. To do this, you can call the WriteLine() method of the StreamWriter class. Once again, after using the stream writer, remember to close it. Here are examples:

Imports System.IO

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, _
		ByVal e As System.EventArgs) _
		Handles Button1.Click
        Dim fstPeople As StreamWriter

        fstPeople = My.Computer.FileSystem.OpenTextFileWriter("People1.ppl", False)

        fstPeople.WriteLine(txtPerson1.Text)
        fstPeople.WriteLine(txtPerson2.Text)
        fstPeople.WriteLine(txtPerson3.Text)
        fstPeople.WriteLine(txtPerson4.Text)
        fstPeople.Close()

        txtPerson1.Text = ""
        txtPerson2.Text = ""
        txtPerson3.Text = ""
        txtPerson4.Text = ""
    End Sub
End Class

Practical LearningPractical Learning: Writing to a Stream

  1. Scroll back down the file and change the code of the btnClose_Click event as follows:
     
    Private Sub btnClose_Click(ByVal sender As Object, _
                                   ByVal e As System.EventArgs) _
                                   Handles btnClose.Click
            Dim Filename As String
            Dim Answer As MsgBoxResult
            Dim IceCreamWriter As StreamWriter
    
            Answer = MsgBox("Do you want to save this order to remember it " & _
                            "the next time you come to " & _
                            "get your ice scream?", _
                            MsgBoxStyle.YesNo Or MsgBoxStyle.Question, _
                            "Ice Cream Vending Machine")
            If Answer = MsgBoxResult.Yes Then
                Filename = InputBox( _
                    "Please type your initials and press Enter", _
                    "Ice Cream Vending Machine", "AA", 100, 100)
                If Filename <> "" Then
                    Filename = Filename & ".icr"
    
                    IceCreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Filename, False)
                    
                    IceCreamWriter.WriteLine(dtpOrderDate.Value.ToShortDateString())
                    IceCreamWriter.WriteLine(dtpOrderTime.Value.ToShortTimeString())
                    IceCreamWriter.WriteLine(cboFlavors.Text)
                    IceCreamWriter.WriteLine(cboContainers.Text)
                    IceCreamWriter.WriteLine(cboIngredients.Text)
                    IceCreamWriter.WriteLine(txtScoops.Text)
                    IceCreamWriter.WriteLine(txtOrderTotal.Text)
    
                    IceCreamWriter.Close()
    
                    MsgBox("The order has been saved")
                Else
                    MsgBox("The ice cream order will not be saved")
                End If
            End If
    
            MsgBox("Good Bye: It was a delight serving you")
            Close()
    End Sub
  2. Execute the application and create an ice cream order. Here is an example:
     
    Clarksville Ice Cream
    Clarksville Ice Cream
    Clarksville Ice Cream
    Clarksville Ice Cream
  3. Close the form and return to your programming environment

Stream Reading

 

Binary Reading 

As opposed to writing to a stream, you may want to read existing data from it. Before doing this, you can first specify your intent to the streaming class using the FileMode enumerator. This can be done using the FileStream class as follows:

Private Sub btnOpen_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click

        Dim Filename As String = "Persons.prs"

        Dim PersonsStreamer As FileStream = _
            New FileStream(Filename, FileMode.Create)
End Sub

Once the stream is ready, you can get prepared to read data from it. To support this, you can use the BinaryReader class. This class provides two constructors. One of the constructors (the first) has the following syntax:

Public Sub New(input As Stream)

This constructor takes as argument a Stream value, which could be a FileStream object. After declaring a FileStream variable using this constructor, you can read data from it. To support this, the class provides an appropriate method for each primitive data type.

After using the stream, you should close it to reclaim the resources it was using. This is done by calling the Close() method.

Here is an example of using the mentioned methods:

Private Sub btnOpen_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click

        Dim Filename As String = "Persons.prs"
        Dim PersonsStreamer As FileStream
        Dim PersonsReader As BinaryReader

        PersonsStreamer = New FileStream(Filename, FileMode.Open)
        PersonsReader = New BinaryReader(PersonsStreamer)

        txtPerson1.Text = PersonsReader.ReadString()
        txtPerson2.Text = PersonsReader.ReadString()
        txtPerson3.Text = PersonsReader.ReadString()
        txtPerson4.Text = PersonsReader.ReadString()

        PersonsReader.Close()
        PersonsStreamer.Close()
End Sub

Stream Reading

Besides the BinaryReader class that reads its values in binary format, the .NET Framework supports character reading through a class called StreamReader. The StreamReader class is based on the TextReader class. Like its counterpart the StramWriter class, StreamReader is equipped with various constructors. If you want to read values from a file, you can pass its name or path to the following constructor:

Public Sub New(path As String)

Alternatively, to a FileStream object, you can pass it to the following constructor of the StreamReader class to create a stream:

Public Sub New (stream As Stream)

This method takes as argument a Stream-based variable, which could be a FileStream value. If/since you are planning to read from a stream, configure your file mode status appropriately. Here is an example:

Private Sub btnOpen_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click
        Dim Filename As String = "Student.std"

        Dim StudentsStreamer As FileStream
        Dim StudentsReader As StreamReader

        StudentsStreamer = New FileStream(Filename, FileMode.Open)
        StudentsReader = New StreamReader(StudentsStreamer)
End Sub

After creating a StreamReader object, you can read data from the file. To support this, the TextReader class is equipped with the Write() method that the StreamReader class inherits. The StreamReader class itself is equipped with the ReadLine() method. Here is an example of calling it:

Private Sub btnOpen_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click
        Dim Filename As String = "Student.std"

        Dim StudentsStreamer As FileStream
        Dim StudentsReader As StreamReader

        StudentsStreamer = New FileStream(Filename, FileMode.Open)
        StudentsReader = New StreamReader(StudentsStreamer)

        txtFirstName.Text = StudentsReader.ReadLine()
        txtLastName.Text = StudentsReader.ReadLine()
        cbxGenders.SelectedIndex = CInt(StudentsReader.ReadLine())

        StudentsReader.Close()
        StudentsStreamer.Close()
End Sub

Using My File System

To read text from a file using the FileSystem class from My object, you can call the OpenTextFileReader() method. It comes in two versions whose syntaxes are:

Public Shared Function OpenTextFileReader( _
   ByVal file As String, 
) As System.IO.StreamReader

Public Shared Function OpenTextFileReader( _
   ByVal file As String, _
   ByVal encoding As System.Text.Encoding _
) As System.IO.StreamReader

The first argument is the name of, or the path to, the file that will receive the new values. The encoding argument allows you to specify the type of text that you want to use.

This method returns a StreamReader value. After creating the stream reader, you can then read values from it. To do this, you can call the ReadLine() method of the StreamReader class. Once again, after using the stream reader, remember to close it. Here are examples:

Private Sub Button2_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles Button2.Click
        Dim fstPeople As StreamReader

        fstPeople = My.Computer.FileSystem.OpenTextFileReader("People1.ppl")

        txtPerson1.Text = fstPeople.ReadLine
        txtPerson2.Text = fstPeople.ReadLine
        txtPerson3.Text = fstPeople.ReadLine
        txtPerson4.Text = fstPeople.ReadLine

        fstPeople.Close()
End Sub

Practical LearningPractical Learning: Reading From a Stream

  1. Access the Code and, in the Class Name combo box, select (Exercise Events)
  2. In the Method Name combo box, select Load and implement the event as follows:
     
    Private Sub Exercise_Load(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) _
                                  Handles Me.Load
            Dim OrderDate As String, OrderTime As String
            Dim SelectedFlavor As String
            Dim SelectedContainer As String
            Dim SelectedIngredient As String
            Dim Scoops As String, OrderTotal As String
            Dim Filename As String
            Dim IceCreamReader As StreamReader
    
            Filename = InputBox( _
                   "If you had previously ordered an ice cream here " & _
                   "and you want to order the same, please type your " & _
                   "initials and press Enter (otherwise, press Esc)", _
                   "Ice Cream Vending Machine", "", 100, 100)
            If Filename <> "" Then
                Filename = Filename & ".icr"
    
                IceCreamReader = My.Computer.FileSystem.OpenTextFileReader(Filename)
    
                ' Find out if this order was previously saved in the machine
                If My.Computer.FileSystem.FileExists(Filename) Then
                    ' If so, open it
                    OrderDate = IceCreamReader.ReadLine()
                    OrderTime = IceCreamReader.ReadLine()
                    SelectedFlavor = IceCreamReader.ReadLine()
                    SelectedContainer = IceCreamReader.ReadLine()
                    SelectedIngredient = IceCreamReader.ReadLine()
                    Scoops = IceCreamReader.ReadLine()
                    OrderTotal = IceCreamReader.ReadLine()
    
                    ' And display it to the user
                    dtpOrderDate.Value = DateTime.Parse(OrderDate)
                    dtpOrderTime.Value = DateTime.Parse(OrderTime)
                    cboFlavors.Text = SelectedFlavor
                    cboContainers.Text = SelectedContainer
                    cboIngredients.Text = SelectedIngredient
                    txtScoops.Text = Scoops.ToString()
                    txtOrderTotal.Text = OrderTotal
    
                    IceCreamReader.Close()
                Else
                    MsgBox("It looks like you have not previously " & _
                                 "ordered an ice cream here")
                End If
            End If
    End Sub
  3. Execute the application and test it. Here is an example:
     
    Microsoft Visual Basic Input Box
    Clarksville Ice Cream
  4. Close the form

Exception Handling in File Processing

 

Finally

In previous lessons, to handle exceptions, we were using the Try, Catch, and Throw keywords. These allowed us to perform normal assignments in a Try section and then handle an exception, if any, in a Catch block. We also mentioned that, when you create a stream, the operating system must allocate resources and dedicate them to the file processing operations. Additional resources may be provided for the object that is in charge of writing to, or reading from, the stream. We also saw that, when the streaming was over, we should free the resources and give them back to the operating system. To do this, we called the Close() method of the variable that was using resources.

More than any other assignment, file processing is in prime need of exception handling. During file processing, there are many things that can go wrong. For this reason, the creation and/or management of streams should be performed in a Try block to get ready to handle exceptions that would occur. Besides actually handling exceptions, you can use a special keyword used free resources. This keyword is Finally.

The Finally keyword is used to create a section of an exception. Like Catch, a Finally block cannot exist by itself. It can be created following a Try section. The formula used would be:

try

Finally

End Try

Based on this, the Finally section has a body of its own, delimited by its curly brackets. Like Catch, the Finally section is created after the Try section. Unlike Catch, Finally never has parentheses and never takes arguments. Unlike Catch, the Finally section is always executed. Because the Finally clause always gets executed, you can include any type of code in it but it is usually appropriate to free the resources that were allocated previously. In the same way, you can use a finally section to free resources used when reading from a stream. Here are examples:

Imports System.IO

Public Class Exercise

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnSave.Click
        Dim Filename As String = "Persons.prs"

        Dim PersonsStream As FileStream
        Dim PersonsWriter As BinaryWriter

        PersonsStream = New FileStream(Filename, FileMode.Create)
        PersonsWriter = New BinaryWriter(PersonsStream)

        Try
            PersonsWriter.Write(txtPerson1.Text)
            PersonsWriter.Write(txtPerson2.Text)
            PersonsWriter.Write(txtPerson3.Text)
            PersonsWriter.Write(txtPerson4.Text)
        Finally
            PersonsWriter.Close()
            PersonsStream.Close()
        End Try

        txtPerson1.Text = ""
        txtPerson2.Text = ""
        txtPerson3.Text = ""
        txtPerson4.Text = ""
    End Sub

    Private Sub btnOpen_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click

        Dim Filename As String = "Persons.prs"
        Dim PersonsStreamer As FileStream
        Dim PersonsReader As BinaryReader

        PersonsStreamer = New FileStream(Filename, FileMode.Open)
        PersonsReader = New BinaryReader(PersonsStreamer)

        Try
            txtPerson1.Text = PersonsReader.ReadString()
            txtPerson2.Text = PersonsReader.ReadString()
            txtPerson3.Text = PersonsReader.ReadString()
            txtPerson4.Text = PersonsReader.ReadString()
        Finally
            PersonsReader.Close()
            PersonsStreamer.Close()
        End Try
    End Sub
End Class

Of course, since the whole block of code starts with a Try section, it is used for exception handling. This means that you can add the necessary and appropriate Catch section(s) (but you don't have to).

Practical LearningPractical Learning: Finally Releasing Resources

  1. Right-click the form and click View Code
  2. Change the following two events :
     
    Private Sub btnClose_Click(ByVal sender As Object, _
                                   ByVal e As System.EventArgs) _
                                   Handles btnClose.Click
            Dim Filename As String
            Dim Answer As MsgBoxResult
            Dim IceCreamWriter As StreamWriter
    
            Answer = MsgBox("Do you want to save this order to remember it " & _
                            "the next time you come to " & _
                            "get your ice scream?", _
                            MsgBoxStyle.YesNo Or MsgBoxStyle.Question, _
                            "Ice Cream Vending Machine")
            If Answer = MsgBoxResult.Yes Then
                Filename = InputBox( _
                    "Please type your initials and press Enter", _
                    "Ice Cream Vending Machine", "AA", 100, 100)
                If Filename <> "" Then
                    Filename = Filename & ".icr"
    
                    IceCreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Filename, False)
    
                    Try
                        IceCreamWriter.WriteLine(dtpOrderDate.Value.ToShortDateString())
                        IceCreamWriter.WriteLine(dtpOrderTime.Value.ToShortTimeString())
                        IceCreamWriter.WriteLine(cboFlavors.Text)
                        IceCreamWriter.WriteLine(cboContainers.Text)
                        IceCreamWriter.WriteLine(cboIngredients.Text)
                        IceCreamWriter.WriteLine(txtScoops.Text)
                        IceCreamWriter.WriteLine(txtOrderTotal.Text)
                    Finally
                        IceCreamWriter.Close()
                    End Try
    
                    MsgBox("The order has been saved")
                Else
                    MsgBox("The ice cream order will not be saved")
                End If
            End If
    
            MsgBox("Good Bye: It was a delight serving you")
            Close()
    End Sub
    
    Private Sub Exercise_Load(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) _
                                  Handles Me.Load
            Dim OrderDate As String, OrderTime As String
            Dim SelectedFlavor As String
            Dim SelectedContainer As String
            Dim SelectedIngredient As String
            Dim Scoops As String, OrderTotal As String
            Dim Filename As String
            Dim IceCreamReader As StreamReader
    
            Filename = InputBox( _
                   "If you had previously ordered an ice cream here " & _
                   "and you want to order the same, please type your " & _
                   "initials and press Enter (otherwise, press Esc)", _
                   "Ice Cream Vending Machine", "", 100, 100)
            If Filename <> "" Then
                Filename = Filename & ".icr"
    
                IceCreamReader = My.Computer.FileSystem.OpenTextFileReader(Filename)
    
                ' Find out if this order was previously saved in the machine
                If My.Computer.FileSystem.FileExists(Filename) Then
                    ' If so, open it
    
                    Try
                        OrderDate = IceCreamReader.ReadLine()
                        OrderTime = IceCreamReader.ReadLine()
                        SelectedFlavor = IceCreamReader.ReadLine()
                        SelectedContainer = IceCreamReader.ReadLine()
                        SelectedIngredient = IceCreamReader.ReadLine()
                        Scoops = IceCreamReader.ReadLine()
                        OrderTotal = IceCreamReader.ReadLine()
    
                        ' And display it to the user
                        dtpOrderDate.Value = DateTime.Parse(OrderDate)
                        dtpOrderTime.Value = DateTime.Parse(OrderTime)
                        cboFlavors.Text = SelectedFlavor
                        cboContainers.Text = SelectedContainer
                        cboIngredients.Text = SelectedIngredient
                        txtScoops.Text = Scoops.ToString()
                        txtOrderTotal.Text = OrderTotal
                    Finally
                        IceCreamReader.Close()
                    End Try
    
                Else
                    MsgBox("It looks like you have not previously " & _
                                 "ordered an ice cream here")
                End If
            End If
        End Sub
    End Class
  3. Save the file

The .NET Framework Exception Handling Classes

 

The File Not Found Exception

In the previous lesson as our introduction to file processing, we behaved as if everything was alright. Unfortunately, file processing can be very strict in its assignments. Based on this, the .NET Framework provides various Exception-oriented classes to deal with almost any type of exception you can think of.

One of the most important aspects of file processing is the name of the file that will be dealt with. In some cases you can provide this name to the application or document. In some other cases, you would let the user specify the name of the path. Regardless of how the name of the file would be provided to the operating system, when this name is acted upon, the compiler is asked to work on the file. If the file doesn't exist, the operation cannot be carried. Furthermore, the compiler would throw an error. Here is an example:

private void btnOpen_Click(object sender, EventArgs e)

    Dim Filename as string  = "contractors.spr"
    Dim fstPersons as FileStream  = null
    Dim rdrPersons As BinaryReader  = null

    fstPersons = new FileStream(Filename, FileMode.Open)
    rdrPersons = new BinaryReader(fstPersons)

    try
    
        txtPerson1.Text = rdrPersons.ReadString()
        txtPerson2.Text = rdrPersons.ReadString()
        txtPerson3.Text = rdrPersons.ReadString()
        txtPerson4.Text = rdrPersons.ReadString()
    End 
    finally
    
        rdrPersons.Close()
        fstPersons.Close()
    End 
End 

Here is an example of an error that this would produce:

The FileNotFoundException exception is thrown when a file has not been found. If you click the Details button of the above type of error, you would find out that this is the type of error you get when you provide a wrong path or wrong file name:

File Not Found Exception

To handle the FileNotFoundException exception, you can create its Catch clause. Here is an example:

Private Sub btnOpen_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) _
                              Handles btnOpen.Click

        Dim Filename As String = "People.prs"
        Dim PersonsStreamer As FileStream
        Dim PersonsReader As BinaryReader

        Try
            PersonsStreamer = New FileStream(Filename, FileMode.Open)
            PersonsReader = New BinaryReader(PersonsStreamer)

            Try
                txtPerson1.Text = PersonsReader.ReadString()
                txtPerson2.Text = PersonsReader.ReadString()
                txtPerson3.Text = PersonsReader.ReadString()
                txtPerson4.Text = PersonsReader.ReadString()
            Finally
                PersonsReader.Close()
                PersonsStreamer.Close()
            End Try

        Catch fnfEx As FileNotFoundException
            MsgBox("Error: " & fnfEx.Message _
                   & vbCrLf & _
                   "May be the file doesn't exist or you typed it wrong!")
        End Try
End Sub

Here is an example of what this would produce:

File Not Found Exception Handling

The IO Exception

As mentioned already, during file processing, anything could go wrong. If you don't know what caused an error, you can throw the IOException exception.

Practical LearningPractical Learning: Handling File Processing Exceptions

  1. To handle a FileNotFoundException exception, change the event as follows:
     
    Private Sub Exercise_Load(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) _
                                  Handles Me.Load
            Dim OrderDate As String, OrderTime As String
            Dim SelectedFlavor As String
            Dim SelectedContainer As String
            Dim SelectedIngredient As String
            Dim Scoops As String, OrderTotal As String
            Dim Filename As String
            Dim IceCreamReader As StreamReader
    
            Filename = InputBox( _
                   "If you had previously ordered an ice cream here " & _
                   "and you want to order the same, please type your " & _
                   "initials and press Enter (otherwise, press Esc)", _
                   "Ice Cream Vending Machine", "", 100, 100)
            If Filename <> "" Then
                Filename = Filename & ".icr"
    
                Try
                    IceCreamReader = My.Computer.FileSystem.OpenTextFileReader(Filename)
    
                    ' Find out if this order was previously saved in the machine
                    If My.Computer.FileSystem.FileExists(Filename) Then
                        ' If so, open it
    
                        Try
                            OrderDate = IceCreamReader.ReadLine()
                            OrderTime = IceCreamReader.ReadLine()
                            SelectedFlavor = IceCreamReader.ReadLine()
                            SelectedContainer = IceCreamReader.ReadLine()
                            SelectedIngredient = IceCreamReader.ReadLine()
                            Scoops = IceCreamReader.ReadLine()
                            OrderTotal = IceCreamReader.ReadLine()
    
                            ' And display it to the user
                            dtpOrderDate.Value = DateTime.Parse(OrderDate)
                            dtpOrderTime.Value = DateTime.Parse(OrderTime)
                            cboFlavors.Text = SelectedFlavor
                            cboContainers.Text = SelectedContainer
                            cboIngredients.Text = SelectedIngredient
                            txtScoops.Text = Scoops.ToString()
                            txtOrderTotal.Text = OrderTotal
                        Finally
                            IceCreamReader.Close()
                        End Try
    
                    Else
                        MsgBox("It looks like you have not previously " & _
                                     "ordered an ice cream here")
                    End If
    
                Catch ex As FileNotFoundException
                    MsgBox("There is no previous order with those initials")
                End Try
            End If
    End Sub
  2. Exercise the application and test it
  3. Close the form

Exercises

 

People

  1. Create an application named People1 and design its form as follows:
     
  2. Let the user enter the names of 4 people. When the user clicks Save, display (use) the SaveFileDialog control to allow the user to enter the name of a the file
  3. When the user clicks Open, display (use) the OpenFileDialog control to allow the user to select the file to open

Clarksville Ice Cream

  1. Open the ClarskvilleIceCream2 application from this lesson
  2. Observe the application and create a help file for it
  3. Add tool tips and help to the application
 

Previous Copyright 2008 Yevol Next