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, such as 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 variable of type 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 StreamWriter(Stream stream);

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

private void button1_Click(object sender, System.EventArgs e)
{
             FileStream stmRecords = new FileStream("Records.rcd", FileMode.CreateNew, FileAccess.Write);
             StreamWriter txtMemo = new StreamWriter(stmRecords);
}

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 StreamWriter(string path);

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:

public override void Write(char value);

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 void btnSave_Click(object sender, System.EventArgs e)
{
	FileStream stmWeekdays = new FileStream("Weekdays.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	StreamWriter stmWriter = 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();
}

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:

public void Write(char[] buffer);

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 void btnSave_Click(object sender, System.EventArgs e)
{
	FileStream stmQuarter = new FileStream("Quarter.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	 StreamWriter stmWriter = new StreamWriter(stmQuarter);

	 char[] jan = { 'J', 'a', 'n', 'u', 'a', 'r', 'y' };
	 char[] feb = { 'F', 'e', 'b', 'r', 'u', 'a', 'r', 'y' };
	 char[] mar = { 'M', 'a', 'r', 'c', 'h' };

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

	 stmWriter.Flush();
	 stmQuarter.Flush();
	 stmQuarter.Close();
}

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:

public void Write(string value);

This version expects a string 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 void btnSave_Click(object sender, System.EventArgs e)
{
	FileStream stmRecords = new FileStream("Conserve.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	StreamWriter stmWriter = new StreamWriter(stmRecords);

	for(int i = 0; i < this.textBox1.Lines.Length; i++)
	{
		stmWriter.WriteLine(this.textBox1.Lines[i].ToString());
	}

	stmWriter.Flush();
	stmWriter.Close();
}

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 certain 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:

public: void Write(char[] buffer, int index, int count);

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:

public override int Read();

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 void btnSave_Click(object sender, System.EventArgs e)
{
	FileStream stmRecords = new FileStream("Conserve.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	StreamWriter stmWriter = new StreamWriter(stmRecords);

	for(int i = 0; i < this.textBox1.Lines.Length; i++)
	{
		stmWriter.WriteLine(this.textBox1.Lines[i].ToString());
	}

	stmWriter.Flush();
	stmWriter.Close();
}

private void btnOpen_Click(object sender, System.EventArgs e)
{
	 FileStream fleReader = new FileStream("Conserve.txt", FileMode.Open, FileAccess.Read);
	 StreamReader stmReader = new StreamReader(fleReader);
	 StringBuilder lstChars = new StringBuilder();

	 int iChar = stmReader.Read();
	 lstChars.Append((char)iChar);
	 while(iChar > -1)
	 {
		 iChar = stmReader.Read();
		 lstChars.Append((char)iChar);
	 } 
				 
	 this.textBox1.Text = lstChars.ToString();
	 stmReader.Close();
}

As mentioned already, 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 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. Here is an example that reads the characters written on the Weekdays.txt file we saved earlier:

private void btnSave_Click(object sender, System.EventArgs e)
{
	FileStream stmWeekdays = new FileStream("Weekdays.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	StreamWriter stmWriter = 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();
}

private void button1_Click(object sender, System.EventArgs e)
{
	FileStream stmWeekdays = new FileStream("Weekdays.txt", FileMode.Open, FileAccess.Read);
	StreamReader stmReader = new StreamReader(stmWeekdays);

	this.textBox1.Text = stmReader.ReadLine();
	this.textBox2.Text = stmReader.ReadLine();
	this.textBox3.Text = stmReader.ReadLine();
	this.textBox4.Text = stmReader.ReadLine();
	this.textBox5.Text = stmReader.ReadLine();
	this.textBox6.Text = stmReader.ReadLine();
	this.textBox7.Text = stmReader.ReadLine();

	stmWeekdays.Flush();
	stmWeekdays.Close();
}

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:

System.Void btnSave_Click(System.Object   sender, System.EventArgs   e)
{
	 FileStream stmQuarter = new FileStream("Quarter.txt", FileMode.Create, FileAccess.Write, FileShare.None);
	 StreamWriter stmWriter = new StreamWriter(stmQuarter);

	 char jan[] = { 'J', 'a', 'n', 'u', 'a', 'r', 'y' };
	 char feb[] = { 'F', 'e', 'b', 'r', 'u', 'a', 'r', 'y' };
	 char mar[] = { 'M', 'a', 'r', 'c', 'h' };

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

	 stmWriter.Flush();
	 stmQuarter.Flush();
	 stmQuarter.Close();
}

System.Void btnOpen_Click(System.Object   sender, System.EventArgs   e)
{
	 FileStream stmQuarter = new FileStream("Quarter.txt", FileMode.Open, FileAccess.Read);
	 StreamReader stmReader = new StreamReader(stmQuarter);

	 string strMonth = stmReader.ReadLine();
	 this.textBox1.Text = strMonth;
			 
	 strMonth = stmReader.ReadLine();
	 this.textBox2.Text = strMonth;

	 strMonth = stmReader.ReadLine();
	 this.textBox3.Text = strMonth;

	 stmQuarter.Flush();
	 stmQuarter.Close();
}

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:

public override int Read([In, Out] char[] buffer, int index, int count);

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. Next