Home

Character and String Streaming

 

Introduction

As mentioned earlier, the items to save on a document are primarily considered as bits. This makes it possible to save small pieces of information such as those that would fit a byte, a char, a short, or a double value. To support the ability to write one character at a time to a medium, the System.IO namespace provides the TextWriter class. This class is abstract, meaning you can't initialize a variable with it. Instead, you can use one of its derived classes, particularly the StreamWriter class.

Stream Writing

The operation used to save a character to a stream is performed through the StreamWriter class that is based on this. Therefore, to perform this operation, you can declare a pointer to StreamWriter or to its parent the TextWriter class. The StreamWriter class is equipped with various constructors. This allows you to initialize a stream with an option of your choice. For example, to initialize it using a FileStream object, you can use the following constructor:

Public Sub New(ByVal stm As Stream)

This constructor expects a Stream-type of object as argument. Here is an example of how this constructor can be used:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles Button1.Click
        Dim stmRecords As New FileStream("Records.rcd", FileMode.CreateNew, FileAccess.Write)
        Dim txtMemo As New StreamWriter(stmRecords)
End Sub

If you don't (yet) have a stream you can use, you can directly initialize a file using its name. To do this, you can use the following constructor:

Public Sub New(ByVal path As String)

When using this constructor, you can pass it the name of the file or its (complete) path.

Eventually, after using a Stream-based class, always remember to release its resources by calling its Close() method. Before calling Close(), call the class' Flush() method to clear the memory areas that the object was using when performing its operations.

After creating a character stream, you can write values to it. To support this, the StreamWriter class is equipped with the Write() method. This method is overloaded with four versions. One of the versions uses the following syntax:

Overrides Overloads Public Sub Write(ByVal value As Char)

This method expects as argument a character. This Write() method writes one character, then another immediate call to Write() writes the next character on the same line. This can be convenient in many cases. In some other cases, you may want each character to be written on its own line. To write each character on its own line, use the WriteLine() method instead. The WriteLine() method is inherited from the TextWriter class that is the parent of StreamWriter. It can be used as follows:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim stmWeekdays As New FileStream("Weekdays.txt", FileMode.Create, FileAccess.Write, FileShare.None)
        Dim stmWriter As New StreamWriter(stmWeekdays)

        stmWriter.WriteLine("M")
        stmWriter.WriteLine("T")
        stmWriter.WriteLine("W")
        stmWriter.WriteLine("T")
        stmWriter.WriteLine("F")
        stmWriter.WriteLine("S")
        stmWriter.WriteLine("S")

        stmWriter.Flush()
        stmWeekdays.Flush()
        stmWeekdays.Close()
End Sub

Instead of writing one character at a time, you can write an array of characters to a stream. To do this, you would use the following version of the Write() method:

Overrides Overloads Public Sub Write(ByVal buffer() As Char)

This version takes as argument an array of Char values. This version would write a series of characters of the buffer argument on the same line or the same paragraph. If you make another call to this Write() method to add another series of characters, they would be added to the same line. If you want to writer each array in its own paragraph, you can call the TextWriter.WriteLine() method that the StreamWriter class inherits from its parent. Here is an example:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim stmQuarter As New FileStream("Quarter.txt", FileMode.Create, FileAccess.Write, FileShare.None)
        Dim stmWriter As New StreamWriter(stmQuarter)

        Dim jan As Char() = {"J", "a", "n", "u", "a", "r", "y"}
        Dim feb As Char() = {"F", "e", "b", "r", "u", "a", "r", "y"}
        Dim mar As Char() = {"M", "a", "r", "c", "h"}

        stmWriter.WriteLine(jan)
        stmWriter.WriteLine(feb)
        stmWriter.WriteLine(mar)

        stmWriter.Flush()
        stmQuarter.Flush()
        stmQuarter.Close()
End Sub

Another way you can write characters to a stream is to proceed from a string. This operation is performed through the following version of the Write() method:

Overrides Overloads Public Sub Write(ByVal value As String)

This version expects a String pointer as argument and writes it wholly to the stream. Here is an example from a form equipped with a Multiline TextBox named textBox1 and a Button control named btnSave. When the user clicks the btnSave button, each line, treated as a String value, of the text box is written to a stream:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim stmRecords As New FileStream("Conserve.txt", FileMode.Create, FileAccess.Write, FileShare.None)
        Dim stmWriter As New StreamWriter(stmRecords)
        Dim i As Integer

        For i = 0 To Me.TextBox1.Lines.Length - 1 Step 1
            stmWriter.WriteLine(Me.TextBox1.Lines(i).ToString())
        Next

        stmWriter.Flush()
        stmWriter.Close()
End Sub

The last version of the StreamWriter.Write() method allows you also to write an array of characters to a stream but this time, you don't have to include the whole array, just a set number of characters of the array. In other words, you can select a section of the array and write it to the stream. This method uses the following syntax:

Overrides Overloads Public Sub Write(ByVal buffer() As Char, ByVal index As Integer, ByVal count As Integer)

This method expects an array of Char as the first argument. When writing the characters of this argument to a stream, the second argument specifies the starting character from the array. The last argument specifies the number of characters from the starting index to the end of the array, that would be written to stream.

Stream Reading

As opposed to writing characters, you may want to read them from a stream. To perform this operation, you can use the StreamReader class, which is derived from the TextReader class. To read a character from a stream, the StreamReader class is equipped with the Read() method which is overloaded in two versions. One of the versions uses the following syntax:

Overrides Overloads Public Function Read() As Integer

This method reads one a character from the stream, checks the next character and returns it as an integer. If the next character has a value higher than -1, then the method reads it and advances to the next. Once, or when, the method finds out that the next character has a value of -1, then it stops. Here is an example that reads characters from a stream, one character at a time:

Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
        Dim fleReader As New FileStream("Conserve.txt", FileMode.Open, FileAccess.Read)
        Dim stmReader As New StreamReader(fleReader)
        Dim lstChars As New StringBuilder

        Dim iChar As Integer = stmReader.Read()
        lstChars.Append(Convert.ToChar(iChar))
        Do While stmReader.Peek() >= 0
            iChar = stmReader.Read()
            lstChars.Append(Convert.ToChar(iChar))

            Me.TextBox1.Text = lstChars.ToString()
        Loop

        stmReader.Close()
End Sub

As mentioned earlier, the Write() method of the StreamWriter class writes its values on the same line. This means that, when you read them back using the StreamReader.Read() method, all characters on the same line are read at once. We also mentioned that an alternative was to write each character on its own line using the TextWriter.WriteLine() method. In the same way, to read characters one line at a time, you can call the ReadLine() method. The TextReader.ReadLine() method returns a pointer to String and not a character. This returned value is actually a number that represents the Unicode number of the character, such as 87 but if you access 87 using the StreamReader.Read() method, it would consider that 87 is a string and would therefore read only 8 as the character. This means that, if you had used the StreamWriter.WriteLine() method, you should also use the StreamReader.ReadLine() method to read the number as a string. After reading the line, before using the character, remember to cast it appropriately in order to retrieve the number stored in it. Here is an example that reads the characters written on the Weekdays.txt file we saved earlier:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim stmWeekdays As New FileStream("Weekdays.txt", FileMode.Create, FileAccess.Write, FileShare.None)
        Dim stmWriter As New StreamWriter(stmWeekdays)

        stmWriter.WriteLine("M")
        stmWriter.WriteLine("T")
        stmWriter.WriteLine("W")
        stmWriter.WriteLine("T")
        stmWriter.WriteLine("F")
        stmWriter.WriteLine("S")
        stmWriter.WriteLine("S")

        stmWriter.Flush()
        stmWeekdays.Flush()
        stmWeekdays.Close()
    End Sub

    Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
        Dim stmWeekdays As New FileStream("Weekdays.txt", FileMode.Open, FileAccess.Read)
        Dim stmReader As New StreamReader(stmWeekdays)

        Dim strDay As String = stmReader.ReadLine()
        Me.TextBox1.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox2.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox3.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox4.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox5.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox6.Text = strDay

        strDay = stmReader.ReadLine()
        Me.TextBox7.Text = strDay

        stmWeekdays.Flush()
        stmWeekdays.Close()
    End Sub

In the same way, if you had written characters to a stream using arrays of characters and you want to read each line or paragraph as an entity, you can call the TextReader.ReadLine() method. This time, you may not need to cast the returned value(s). Here is an example:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Dim stmQuarter As New FileStream("Quarter.txt", FileMode.Create, FileAccess.Write, FileShare.None)
        Dim stmWriter As New StreamWriter(stmQuarter)

        Dim jan As Char() = {"J", "a", "n", "u", "a", "r", "y"}
        Dim feb As Char() = {"F", "e", "b", "r", "u", "a", "r", "y"}
        Dim mar As Char() = {"M", "a", "r", "c", "h"}

        stmWriter.WriteLine(jan)
        stmWriter.WriteLine(feb)
        stmWriter.WriteLine(mar)

        stmWriter.Flush()
        stmQuarter.Flush()
        stmQuarter.Close()
    End Sub

    Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
        Dim stmQuarter As New FileStream("Quarter.txt", FileMode.Open, FileAccess.Read)
        Dim stmReader As New StreamReader(stmQuarter)

        Dim strMonth As String = stmReader.ReadLine()
        Me.TextBox1.Text = strMonth

        strMonth = stmReader.ReadLine()
        Me.TextBox2.Text = strMonth

        strMonth = stmReader.ReadLine()
        Me.TextBox3.Text = strMonth

        stmQuarter.Flush()
        stmQuarter.Close()
    End Sub
	 

After retrieving the characters from the array, instead of reading the whole line or paragraph, you may just want a selected number of characters. To read such a section of the line or paragraph, you can call the second version of the StreamReader.Read() method whose syntax is:

Overrides Overloads Public Function Read( _
   <InteropServices.In(), _
   Out()> ByVal buffer() As Char, _
   ByVal index As Integer, _
   ByVal count As Integer _
) As Integer

The first argument of this method is the variable that will return an array of characters. The second argument is the index of the first character that will be considered from the array. The third argument is the number of characters that will be considered.

 
Previous Copyright © 2004-2010 FunctionX, Inc.