2. Streams

In C#, I/O is usually accomplished with the help of objects called streams. A stream is a source or destination of data. C# provides two kinds of stream objects: readers (data sources) and writers (data destinations). A reader object contains methods that your program can call to read data (get input). A writer object contains methods that allow your program to write data (produce output).

2.1. Standard I/O Streams

C# provides three predefined stream objects that you can use. Called the "Standard I/O" streams, they are usually attached to the standard I/O devices -- the screen and the keyboard. They are the following static members of the Console class:

  • Console.Out is the standard output stream. It contains methods like Write() and WriteLine() that send information to the standard output device (usually the screen).

  • Console.In is the standard input stream. It contains methods like ReadLine() that reads a line of input from the standard input device (usually the keyboard).

The third standard stream object, Console.Error, is an output stream that is usually attached to the screen. It is less frequently used, and I won't discuss it further.

You don't often need to use the Console.In and Console.Out streams in a program, because the Console class contains the convenience methods Write(), WriteLine(), and ReadLine() that work quite well. They do their work by delegating to Console.Out and Console.In. I introduce them here as an example of streams, and to make you aware of their existence. However, let me take this opportunity to demonstrate one possible use: by aliasing the standard streams, you can shorten the amount of code you have to type to do Console I/O:

using System;
using System.IO;

class StdStreamDemo {
  static void Main() {
    TextWriter scr = Console.Out; // scr is an alias for Console.Out
    TextReader kb = Console.In;   // kb is an alias for Console.In
    
    scr.Write("What's your name?");
    string name = kb.ReadLine();
    scr.WriteLine("Hello, " + name);
  }
  
}

This program takes advantage of the fact that variables like (Console.Out and Console.In) hold references to objects. We can create an alias for an object by simply defining a variable and storing a reference to the object in it with an assignment statement.