Chapter 31. Reading and Writing Files

Files play an extremely important role on a computer. They hold text, pictures, Microsoft Word documents, spreadsheets, and all sorts of other data. They also hold executable programs, including those that provide the operating system itself.

In this lesson you learn some basic techniques for reading and writing text files. Using some fairly simple techniques, you can use text files to store and retrieve data used by a program.

UNDERSTANDING STREAMS

There are many kinds of files: web pages, video, audio, executable, and many others. At some level, however, files are all the same. They're just a series of bytes stored on a file system somewhere.

Thinking about files at this very low level enables you to treat them uniformly. That is, you can define common classes and methods that you can then use to manipulate any kind of file.

Many programming languages, including Visual Basic, make working with files at a low level easier by defining the concept of a stream. A stream is simply an ordered series of bytes.

Note

Streams can also represent things other than files. For example, a stream could represent data being sent from one program to another, a series of bytes being downloaded from a web site, or the flow of data as it moves through some complex process such as encryption or compression. This lesson focuses on file streams.

Stream objects provide methods for manipulating streams at a low level. For example, the Stream class provides Read and Write methods that move bytes of data between the stream and an array of bytes in your program.

Working with streams at this low level is convenient for some programs, but it makes day-to-day file handling difficult. You probably don't want to read the bytes from a text file and then reassemble them into characters.

The StreamReader and StreamWriter classes make reading and writing text streams much easier. As you can probably guess from their names, StreamReader enables a program to read text from a stream, and StreamWriter enables a program to write text into a stream. If that stream happens to represent a file, then you're reading and writing files.

Note

The .NET Framework uses namespaces to categorize the classes it provides so they are easier to find and organize. The StreamReader and StreamWriter classes are in the System.IO namespace, so you can refer to them as System.IO.StreamReader and System.IO.StreamWriter.

However, to make it easier to use these classes, you can add the following Imports directive at the very beginning of a code file:

Imports System.IO

After adding that directive, you can refer to these classes without the System.IO prefix.

WRITING FILES

The StreamWriter class provides several constructors to build a StreamWriter associated with different kinds of streams. One of the simplest constructors takes a filename as a parameter. It opens the file for writing and associates the new StreamWriter with it.

Before you create a StreamReader or StreamWriter, however, you should know a bit about the Dispose method and the Using statement (see the accompanying "Using Using" sidebar).

The following code shows how a program can open the file Memo.txt for writing. If the file already exists, it is overwritten.

' Write into the file, overwriting it if it exists.
Using memoWriter As New StreamWriter("Memo.txt")
    ' Write into the file.
    '...
End Using

Note

If you pass the constructor a filename without a path, such as Memo.txt, the program creates the file in its current directory. You can use a fully qualified filename such as C:TempMemo.txt to create the file in a particular directory.

Another version of the class's constructor takes a second Boolean parameter that indicates whether you want to open the file for appending. If you set this parameter to True, the StreamWriter opens the existing file and prepares to add text to the end. If the file doesn't exit, the object silently creates a new file and gets ready to append.

The StreamWriter class provides a Write method to add text to the file. The WriteLine method adds text followed by a new line. Both Write and WriteLine have a bunch of overloaded versions that write various data types into the file: Boolean, Char, String, Integer, Decimal, and so on. They also provide versions that take a format string and parameters, much as the String.Format method does.

The StreamWriter provides one other very important method that I want to cover here: Close. The Close method closes the StreamWriter and its associated file. When you use the Write and WriteLine methods, the StreamWriter may actually buffer its output in memory and only write to the file when it has saved up enough data to make writing to the disk efficient. The Close method forces the StreamWriter to flush its buffer into the file. Until that point, the data may not actually be in the file. If your program crashes or ends without calling Close, there's a very good chance that some or all of your text may be lost.

The following code shows how a program could save the contents of a textbox in a file:

' Write the file, overwriting it if it exists.
Using memoWriter As New StreamWriter("Memo.txt")
    ' Write the file.
    memoWriter.Write(txtMemo.Text)
    memoWriter.Close()
End Using

READING FILES

The StreamReader class enables you to easily read text from a file. Like the StreamWriter class, StreamReader provides a constructor that takes a parameter specifying the name of the file to open. It also implements IDisposable, so you should call a StreamReader's Dispose method or use it in a Using statement.

Note that the constructor throws an exception if the file doesn't exist, so your program should verify that the file is there before you try to open it. One way to do that is to use the File class's static Exists method. For example, the code File.Exists("Memo.txt") returns True if the file Memo.txt exists in the program's current directory.

The StreamReader class provides a Read method that enables reading from the file one or more bytes at a time, but usually you'll want to use its ReadLine and ReadToEnd methods.

As you may be able to guess, ReadLine reads the next line from the file and returns it as a string. ReadToEnd reads the rest of the file from the current position onward and returns it as a string.

The following code reads the file Memo.txt and displays its contents in a textbox:

' Read the file.
Using memoReader As New StreamReader("Memo.txt")
    txtMemo.Text = memoReader.ReadToEnd()
    memoReader.Close()
End Using

The StreamReader's EndOfStream property returns True if the reader is at the end of the stream. This is particularly useful when reading a stream of unknown length. For example, the program can enter a While loop that uses ReadLine to read lines and continue as long as EndOfStream is false.

TRY IT

In this Try It, you build the program shown in Figure 31-1. When the program starts, it loads previously saved values into its textboxes. When it stops, the program saves the values that are currently in the textboxes.

FIGURE 31-1

Figure 31.1. FIGURE 31-1

Note

You can download the code and resources for this Try It from the book's web page at www.wrox.com or www.vb-helper.com/24hourvb.html. You can find them in the Lesson31 folder of the download.

Lesson Requirements

In this lesson:

  • Start a new project and arrange its form as shown in Figure 31-1.

  • Give the form a Load event handler that uses a StreamReader to open the file Values.txt and read the file's lines into the form's textboxes.

  • Give the form a FormClosing event handler that uses a StreamWriter to open the file Values.txt and write the values in the textboxes into the file.

Hints

  • Use an Imports System.IO directive.

  • Use the StreamReader and StreamWriter inside Using blocks.

  • Make sure the file exists before you try to open it.

  • Use a module-scope constant to hold the file's name so all of the code can share it.

Step-by-Step

  • Start a new project and arrange its form as shown in Figure 31-1.

    1. This is reasonably straightforward.

  • Give the form a Load event handler that uses a StreamReader to open the file Values.txt and read the file's lines into the form's textboxes.

    1. Use code similar to the following:

      ' The file's name.
      Private Const FileName As String = "Values.txt"
      
      ' Load the saved values.
      Private Sub Form1_Load() Handles MyBase.Load
          ' See if the file exists.
          If File.Exists(FileName) Then
              ' Open the file.
              Using valueReader As New StreamReader(FileName)
                  txtFirstName.Text = valueReader.ReadLine()
                  txtLastName.Text = valueReader.ReadLine()
                  txtStreet.Text = valueReader.ReadLine()
                  txtCity.Text = valueReader.ReadLine()
                  txtState.Text = valueReader.ReadLine()
                  txtZip.Text = valueReader.ReadLine()
                  valueReader.Close()
              End Using
          End If
      End Sub
  • Give the form a FormClosing event handler that uses a StreamWriter to open the file Values.txt and write the values in the textboxes into the file.

    1. Use code similar to the following:

      ' Save the current values.
      Private Sub Form1_FormClosing() Handles Me.FormClosing
          ' Create the file.
          Using As New StreamWriter(FileName)
              valueWriter.WriteLine(txtFirstName.Text)
              valueWriter.WriteLine(txtLastName.Text)
              valueWriter.WriteLine(txtStreet.Text)
              valueWriter.WriteLine(txtCity.Text)
              valueWriter.WriteLine(txtState.Text)
              valueWriter.WriteLine(txtZip.Text)
              valueWriter.Close()
          End Using
      End Sub

Note

Please select Lesson 31 on the DVD to view the video that accompanies this lesson.

EXERCISES

  1. Build a Memo program that saves and loads a single memo saved in the file in a multiline textbox. Hint: Should you use Write or WriteLine? (This is so easy I wouldn't normally use it as an exercise but it's actually useful. You can use it to record notes during the day and easily review them the next day.)

  2. Make a program that lets the user select a number N from a NumericUpDown control and then generates a file containing a multiplication table showing the products 1 × 1 through N × N. Use formatting to make the numbers line up in columns.

  3. Build a program with a TextBox, a ListBox, an Add button, and a Save button. When the user enters a value in the TextBox and clicks Add, add the value to the ListBox. When the user clicks Save, write the values from the ListBox into a file and then clear the ListBox. When the form loads, make it read the values back into the ListBox.

  4. Build a simple text editor. Give it a MenuStrip with Open and Save commands and a TextBox. Use an OpenFileDialog and a SaveFileDialog to let the user select the file to open and save. (Don't worry about any of the other things a real editor would need to handle, such as locked files and ensuring that the user doesn't close the program with unsaved changes.)

Note

You can find solutions to this lesson's exercises in the Lesson31 folder inside the download available on the book's web site at www.wrox.com or www.vb-helper.com/24hourvb.html.

EXERCISES
..................Content has been hidden....................

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