Home > Articles > Programming > Windows Programming

Hello, C#

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

1.5 Opening a Text File for Reading and Writing

Let's assume that the user has entered a valid text file name for the program. Our job, then, is to open the file, read its contents, and after processing those contents, write the results out to a second file, which we need to create. Let's see how we do this.

Support for file input/output is encapsulated in the System.IO namespace. So the first thing we need to do is open the namespace to the compiler:

using System.IO;

Text files are read and written through the StreamReader and StreamWriter classes. There are various ways to create instances of these classes—for example,

string file_name = @"C:\fictions\gnome.txt";

StreamReader freader = File.OpenText( file_name );
StreamWriter fwriter =
		File.CreateText( @"C:\fictions\gnome.diag" );

OpenText() returns a StreamReader instance bound to the file represented by the string argument passed to it. In this case, it opens a text file stored in the fictions directory on drive C:. The file represented by the string must exist, and the user must have permission to open it; otherwise OpenText() throws an exception.

The @ character identifies the string literal that follows it as a verbatim string literal. In an ordinary string literal, a backslash is treated as a special character. For example, when we write "\n", the backslash and the n are interpreted as an escape sequence representing the new-line character. When we wish an actual backslash to appear in a string literal, we must escape it by preceding it with an additional backslash—for example,

 string fname1 = "C:\\programs\\primer\\basic\\hello.cs";

Within a verbatim string literal, special characters, such as the backslash, do not need to be escaped.

A second difference between an ordinary and a verbatim string literal is the ability of a verbatim string literal to span multiple lines. The nested white space within the multiple-line verbatim string literal, such as a new-line character or a tab, is preserved. This allows for the storage and generation of formatted text blocks. For example, here is how we might implement display_usage():

public void display_usage()
{
  string usage =
   @"usage: WordCount [-s] [-t] [-h] textfile.txt
     where [] indicates an optional argument
      -s prints a series of performance measurements
      -t prints a trace of the program
      -h prints this message";
  Console.WriteLine( usage );
}

CreateText() returns a StreamWriter instance. The file represented by the string argument passed to it, if it exists, is overwritten. To append to a file's existing text rather than overwriting it, we use AppendText().

StreamReader provides a collection of read methods allowing us to read a single character, a block of characters, or, using ReadLine(), a line of text. (There is also a Peek() method to read one character ahead without extracting it from the file.) StreamWriter provides instances of both WriteLine() and Write().

The following code segment reads each line of a text file in turn, assigning it to the string object text_line. StreamReader signals that it has reached the end of the file by returning a null string. The additional parentheses around the assignment of text_line are necessary because of what is called operator precedence (see Section 1.18.4 for a discussion):

 string text_line;
while (( text_line = freader.ReadLine() ) != null )
{
   // write to output file
   fwriter.WriteLine( text_line );
}

// must explicitly close the readers
freader.Close();
fwriter.Close();

When we finish with the readers, we must invoke their associated Close() member functions in order to free the resources associated with them.6

  • + Share This
  • 🔖 Save To Your Account