.NETではConsoleクラスのメソッドを使うことで自プロセスの標準入力(standard input, stdin)や標準出力(standard output, stdout)などの標準ストリーム(standard streams)に対する入出力操作を行うことができるようになっています。

Console.WriteLine等のメソッドで標準出力への書き込みConsole.ReadLine等のメソッドで標準入力からの読み込みが行えます。 また、Console.In/Console.Outプロパティを参照することで標準入出力をTextReader/Textwriterとして参照することもできます。 標準エラー(standard error, stderr)への出力にはConsole.Errorプロパティを使用します。

ファイルに対する入出力を行うStream派生クラスとしてFileStreamクラスが存在しますが、.NETには標準ストリームに直接対応するStream派生クラスは公開されていません(StandardStreamのようなクラスは存在しない)。 そのかわりに、Console.OpenStandardOutputなどのメソッドを使って標準ストリームに対応するStreamを取得できるため、ファイルと同様に標準ストリームを扱うこともできるようになっています。 このほか、標準ストリームをリダイレクトして、標準ストリームの入出力先をFileStreamMemoryStreamなどに変更することもできます。

ここでは、Consoleクラスを使って自プロセスの標準ストリームを操作する方法について解説します。 子プロセスを起動して、そのプロセスの標準ストリームを操作する方法については子プロセスの標準入出力にて解説しています。

標準ストリームに対する読み込み・書き込み

標準ストリームに対する読み込み・書き込みは、Consoleクラスに用意されている静的メソッドを呼び出すことで行うことができます。

標準出力への書き込み

ConsoleクラスのメソッドWrite, WriteLineなどを使うことで標準出力への書き込みを行うことができます。 標準出力の実際の出力先はコンソールウィンドウ、リダイレクトされたファイルやIDEの出力ペインなどとなり、アプリケーションの種類や実行環境によって変わります。

Console.Write・WriteLineメソッドで標準出力に文字列を書き込む
using System;

class Sample {
  static void Main()
  {
    Console.Write("Hello, ");    // 改行なしで標準出力に書き込む
    Console.WriteLine("world!"); // 改行付きで標準出力に書き込む
    Console.WriteLine("Hello, world!");
  }
}
Console.Write・WriteLineメソッドで標準出力に文字列を書き込む
Imports System

Class Sample
  Shared Sub Main()
    Console.Write("Hello, ")    ' 改行なしで標準出力に書き込む
    Console.WriteLine("world!") ' 改行付きで標準出力に書き込む
    Console.WriteLine("Hello, world!")
  End Sub
End Class
実行結果
Hello, world!
Hello, world!

Write, WriteLineメソッドでは書式を指定した書き込みもできるようになっています。

Console.WriteLineメソッドで書式を指定して数値・日時などの値を標準出力に書き込む
using System;

class Sample {
  static void Main()
  {
    var intValue = 42;
    var doubleValue = 3.141592654;
    var dateTimeValue = new DateTime(2013, 8, 24, 1, 2, 3);

    // int double, DateTimeの値をそれぞれ異なる書式で出力する
    Console.WriteLine("{0:D4} {1:N3} {2:hh:ss}", intValue, doubleValue, dateTimeValue);
  }
}
Console.WriteLineメソッドで書式を指定して数値・日時などの値を標準出力に書き込む
Imports System

Class Sample
  Shared Sub Main()
    Dim intValue As Integer = 42
    Dim doubleValue As Double = 3.141592654
    Dim dateTimeValue As New DateTime(2013, 8, 24, 1, 2, 3)

    ' Integer, Double, DateTimeの値をそれぞれ異なる書式で出力する
    Console.WriteLine("{0:D4} {1:N3} {2:hh:ss}", intValue, doubleValue, dateTimeValue)
  End Sub
End Class
実行結果
0042 3.142 01:03

書式を指定した書き込みについては書式指定子で解説しています。

標準入力からの読み込み

ReadLineメソッドを使うことで標準入力から1行分の文字列を読み込むことができます。 ReadLineメソッドの戻り値には改行文字は含まれないため、末尾の改行文字を取り除くchomp/chopのような操作は不要です。

Console.ReadLineメソッドで標準入力から一行分の文字列を読み込む
using System;

class Sample {
  static void Main()
  {
    Console.WriteLine("何か入力してください");

    // 標準入力から一行読み込む
    var text = Console.ReadLine();

    // 標準入力から読み込んだ文字列を標準出力に書き込む
    Console.WriteLine("'{0}'と入力されました", text);
  }
}
Console.ReadLineメソッドで標準入力から一行分の文字列を読み込む
Imports System

Class Sample
  Shared Sub Main()
    Console.WriteLine("何か入力してください")

    ' 標準入力から一行読み込む
    Dim text = Console.ReadLine()

    ' 標準入力から読み込んだ文字列を標準出力に書き込む
    Console.WriteLine("'{0}'と入力されました", text)
  End Sub
End Class
キー入力を使った場合の実行例
>sample.exe
何か入力してください
Hello, world!
'Hello, world!'と入力されました
パイプを使った場合の実行例
>type sample.txt
Hello, line1!
Hello, line2!
Hello, line3!

>type sample.txt | sample.exe
何か入力してください
'Hello, line1!'と入力されました

コマンドプロンプトで実行した場合(標準入力がターミナルに接続されている場合)は、ReadLineメソッドはエンターキーが押されるまで待機します。 標準入力がパイプ等に接続されている場合は、その接続先から1行分読み込んだ時点で処理が戻ります。 なお、ReadLineメソッドではCR/LF/CRLFのいずれかを改行として扱います。

またReadLineメソッドは、リダイレクトパイプで渡される内容が終端(EOF)に達した場合や、コンソールアプリケーションにおいてCTRL+Z(LinuxではCTRL+D)によって入力を中断した場合など、それ以上標準入力から読み込める文字列がない場合にはnull/Nothingを返します。

Console.ReadLineメソッドで標準入力から読み込める内容がなくなるまで読み込む
using System;

class Sample {
  static void Main()
  {
    var lineNumber = 0;

    while (true) { // 無限ループ
      // 標準入力から一行読み込む
      var line = Console.ReadLine();

      if (line == null) {
        // 読み込める文字列が無くなった
        break;
      }
      else {
        // 読み込んだ文字列に行番号を付けて標準出力に書き込む
        lineNumber++;
        Console.WriteLine("{0}: {1}", lineNumber, line);
      }
    }
  }
}
Console.ReadLineメソッドで標準入力から読み込める内容がなくなるまで読み込む
Imports System

Class Sample
  Shared Sub Main()
    Dim lineNumber As  Integer = 0

    While True ' 無限ループ
      ' 標準入力から一行読み込む
      Dim line As String = Console.ReadLine()

      If line Is Nothing Then
        ' 読み込める文字列が無くなった
        Exit While
      Else
        ' 読み込んだ文字列に行番号を付けて標準出力に書き込む
        lineNumber += 1
        Console.WriteLine("{0}: {1}", lineNumber, line)
      End If
    End While
  End Sub
End Class
キー入力を使った場合の実行例
>sample.exe
line1
1: line1
line2
2: line2
line3
3: line3
^Z
パイプを使った場合の実行例
>type sample.txt
line1
line2
line3

>type sample.txt | sample.exe
1: line1
2: line2ReadメソッドはReadLineメソッドとは異なり
3: line3

コンソールアプリケーションではCTRL+Cを押下することでアプリケーションが中断します。 CTRL+Cが押下されたときの動作を変更したい場合は、Console.CancelKeyPressイベントにイベントハンドラを設定することで動作を定義することができます。

標準入出力との接続については§.標準ストリームのリダイレクト子プロセスの標準入出力 §.自プロセスと子プロセスの標準ストリームをパイプする、リダイレクト・パイプなどコマンドラインでの操作についてはMS-DOSコマンドプロンプトTips §.パイプとリダイレクトを参照してください。


Readメソッドを使うと標準入力から1文字ずつ読み込むことができます。 ReadLineメソッドとは異なり、Readメソッドでは改行文字もそのまま読み込まれます

Readメソッドは読み込んだ文字をchar/Char型の範囲の数値(int/Integer型)として返すため、文字として参照する場合は戻り値をChar型にキャストします。 標準入力から読み込める文字列がなくなった場合やCTRL+Zによって入力を中断した場合、Readメソッドは-1を返します。

Console.Readメソッドで標準入力から1文字ずつ読み込む
using System;

class Sample {
  static void Main()
  {
    while (true) { // 無限ループ
      // 標準入力から一文字読み込む
      int ch = Console.Read();

      if (ch == -1) {
        // 読み込める文字列が無くなった
        break;
      }
      else {
        // 読み込んだ文字にかっこを付けて標準出力に書き込む
        var c = (char)ch;

        Console.Write($"[{c}]");
      }
    }
  }
}
Console.Readメソッドで標準入力から1文字ずつ読み込む
Imports System

Class Sample
  Shared Sub Main()
    While True ' 無限ループ
      ' 標準入力から一文字読み込む
      Dim ch As Integer = Console.Read()

      If ch = -1 Then
        ' 読み込める文字列が無くなった
        Exit While
      Else
        ' 読み込んだ文字にかっこを付けて標準出力に書き込む
        Dim c As Char = ChrW(ch)

        Console.Write($"[{c}]")
      End If
    End While
  End Sub
End Class
キー入力を使った場合の実行例
>sample.exe
f[f]o[o]o[o]
[
]b[b]a[a]r[r]
[
]
^Z
パイプを使った場合の実行例
>type sample.txt
foo
bar

>type sample.txt | sample.exe
[f][o][o][
][b][a][r][
]

ReadLine, Readメソッドではキー入力された文字はそのままコンソールウィンドウにも表示されます(エコーバックされる)。 キー入力を表示したくない場合、エコーバックしないようにしたい場合はReadKeyメソッドを使うことができます。

ReadKeyメソッドの使用例はエコーバックせずに文字列を入力する(Console.ReadKey)をご覧ください。

標準入出力のReader/Writer

Console.InプロパティConsole.Outプロパティを使うことでも標準入出力への読み書きを行うことができます。 Console.WriteLineConsole.Out.WriteLineはどちらも標準出力への書き込み、Console.ReadLineConsole.In.ReadLineは標準入力からの読み込みを行います。 動作および結果はどちらも同じです。

Console.Outを使って標準出力へ書き込む
using System;

class Sample {
  static void Main()
  {
    // 以下の2つはどちらも同じ動作・同じ結果となる

    // Consoleクラスのメソッドを使って標準出力に書き込む
    Console.WriteLine("Hello, world!");

    // Console.Outプロパティを使って標準出力に書き込む
    Console.Out.WriteLine("Hello, world!");
  }
}

Console.Outを使って標準出力へ書き込む
Imports System

Class Sample
  Shared Sub Main()
    ' 以下の2つはどちらも同じ動作・同じ結果となる

    ' Consoleクラスのメソッドを使って標準出力に書き込む
    Console.WriteLine("Hello, world!")

    ' Console.Outプロパティを使って標準出力に書き込む
    Console.Out.WriteLine("Hello, world!")
  End Sub
End Class
Console.Inを使って標準入力から読み込む
using System;

class Sample {
  static void Main()
  {
    // 以下の2つはどちらも同じ動作・同じ結果となる

    // Consoleクラスのメソッドを使って標準入力から読み込む
    var line1 = Console.ReadLine();

    // Console.Inプロパティを使って標準入力から読み込む
    var line2 = Console.In.ReadLine();
  }
}
Console.Inを使って標準入力から読み込む
Imports System

Class Sample
  Shared Sub Main()
    ' 以下の2つはどちらも同じ動作・同じ結果となる

    ' Consoleクラスのメソッドを使って標準入力から読み込む
    Dim line1 As String = Console.ReadLine()

    ' Console.Inプロパティを使って標準入力から読み込む
    Dim line2 As String = Console.In.ReadLine()
  End Sub
End Class

Console.In/Outは、それぞれ標準入出力への読み書きを行うTextReader/TextWriterとなっています。 このため、標準入出力をファイル入出力などと同様に扱いたい場合などにこれらのプロパティを活用することができます。 Console.In/Console.Outは、JavaにおけるSystem.in/System.outや、Pythonにおけるsys.stdin/sys.stdoutに相当するものと言えます。

標準エラーへの書き込みを行うTextWriterを取得するためのConsole.Errorプロパティも存在します。

標準ストリームをTextReader/Writerではなく、Streamで扱いたい場合はConsole.OpenStandardInputなどのメソッドを使用します。


Console.Inを使った一例を挙げます。 Consoleクラスには標準入力に書き込まれる内容すべてを読み込むメソッドは存在しませんが、TextReaderにはReadToEndメソッドが用意されているため、これを使って標準入力の内容すべてを読み込むことができます。

Console.In.ReadToEndメソッドを使って標準入力の内容をすべて読み込む
using System;

class Sample {
  static void Main()
  {
    // ReadToEndメソッドで標準入力の内容をすべて読み込む
    var text = Console.In.ReadToEnd();

    // 読み込んだ内容を出力する
    Console.WriteLine("(length = {0})", text.Length);
    Console.WriteLine(text);
  }
}
Console.In.ReadToEndメソッドを使って標準入力の内容をすべて読み込む
Imports System

Class Sample
  Shared Sub Main()
    ' ReadToEndメソッドで標準入力の内容をすべて読み込む
    Dim text As String = Console.In.ReadToEnd()

    ' 読み込んだ内容を出力する
    Console.WriteLine("(length = {0})", text.Length)
    Console.WriteLine(text)
  End Sub
End Class
キー入力を使った場合の実行例
>sample.exe
line1
line2
line3
^Z
(length = 21)
line1
line2
line3

パイプを使った場合の実行例
>type sample.txt
line1
line2
line3

>type sample.txt | sample.exe
(length = 21)
line1
line2
line3

コンソールアプリケーションの場合、上記のコードはCTRL-Z(LinuxではCTRL+D)で標準入力への入力を終了しない限りReadToEndメソッドから処理が戻らず待機状態になります。

コマンドラインでのリダイレクト・パイプと標準入出力との接続についてはMS-DOSコマンドプロンプトTips §.パイプとリダイレクトを参照してください。


XmlDocumentクラスなどではTextReader/TextWriterを入力元・出力先とすることができるようになっています。 こういったクラスでは、Console.In/Console.Outを指定することで標準入出力から直接読み書きすることができるようになります。

TextReader/TextWriterの代わりに標準入出力を入出力先に設定して読み書きを行う
using System;
using System.Xml;

class Sample {
  static void Main()
  {
    var doc = new XmlDocument();

    // 標準入力の内容をXMLとして読み込む
    doc.Load(Console.In);

    // ルート要素下に新しい要素を追加する
    doc.DocumentElement.AppendChild(doc.CreateElement("bar"))
                       .AppendChild(doc.CreateTextNode("bar"));

    // 編集したXMLを標準出力に書き込む
    doc.Save(Console.Out);
  }
}
TextReader/TextWriterの代わりに標準入出力を入出力先に設定して読み書きを行う
Imports System
Imports System.Xml

Class Sample
  Shared Sub Main()
    Dim doc As New XmlDocument()

    ' 標準入力の内容をXMLとして読み込む
    doc.Load(Console.In)

    ' ルート要素下に新しい要素を追加する
    doc.DocumentElement.AppendChild(doc.CreateElement("bar")).AppendChild(doc.CreateTextNode("bar"))

    ' 編集したXMLを標準出力に書き込む
    doc.Save(Console.Out)
  End Sub
End Class
実行結果例
>type sample.xml
<?xml version="1.0" ?>
<doc>
  <foo>foo</foo>
</doc>

>type sample.xml | sample.exe
<?xml version="1.0"?>
<doc>
  <foo>foo</foo>
  <bar>bar</bar>
</doc>

標準エラー

Console.WriteLineConsole.ReadLineなど、直接対応するメソッドがある標準入出力とは異なり、Consoleクラスには直接標準エラーへ書き込むためのメソッドは用意されていません。

標準エラーへの書き込みを行う場合は、Console.Errorプロパティを使って書き込みを行います。 Console.ErrorもConsole.Outと同様、標準エラーへの書き込みを行うTextWriterとなっています。

標準出力と同様、標準エラーの実際の出力先はコンソールウィンドウ、リダイレクトされたファイルやIDEの出力ペインなどとなり、アプリケーションの種類や実行環境によって変わります。

Console.Error.WriteLineメソッドで標準エラーへ書き込む
using System;

class Sample {
  static void Main()
  {
    // 標準出力への書き込み
    Console.WriteLine("Hello, stdout!");
    Console.Out.WriteLine("Hello, stdout!");

    // 標準エラーへの書き込み
    Console.Error.WriteLine("Hello, stderr!");
  }
}
Console.Error.WriteLineメソッドで標準エラーへ書き込む
Imports System

Class Sample
  Shared Sub Main()
    ' 標準出力への書き込み
    Console.WriteLine("Hello, stdout!")
    Console.Out.WriteLine("Hello, stdout!")

    ' 標準エラーへの書き込み
    Console.Error.WriteLine("Hello, stderr!")
  End Sub
End Class
実行結果
>sample.exe
Hello, stdout!
Hello, stdout!
Hello, stderr!

>sample.exe > stdout.txt 2> stderr.txt

>type stdout.txt
Hello, stdout!
Hello, stdout!

>type stderr.txt
Hello, stderr!

コマンドラインでのリダイレクト・パイプと標準入出力との接続についてはMS-DOSコマンドプロンプトTips §.パイプとリダイレクトを参照してください。

標準ストリームの取得

Console.In/Out/ErrorはTextReader/TextWriterであり、これはテキストデータの入出力には向いているものの、バイナリデータの入出力には不向きです。 標準ストリームでバイナリデータを扱いたい場合などにはOpenStandardInput/OpenStandardOutput/OpenStandardErrorの各メソッドを使います。

これらのメソッドではそれぞれ標準入力・標準出力・標準エラーに対応するStreamを取得することができます。 取得したStreamを使って直接読み書きをできるほか、取得したStreamからBinaryReader/BinaryWriterを作成してバイナリデータの読み書きを行うといったこともできます。

次の例では、標準入力から読み込んだ画像を水平方向に反転し、標準出力に書き込んでいます。

標準入出力のStreamを取得して画像の読み書きを行う
using System;
using System.Drawing;
using System.Drawing.Imaging;

class Sample {
  static void Main()
  {
    // 標準入力のStreamを取得して画像として読み込む
    using (var image = new Bitmap(Console.OpenStandardInput())) {
      // 画像を左右反転する
      image.RotateFlip(RotateFlipType.RotateNoneFlipX);

      // 標準出力のStreamを取得して加工した画像を書き込む
      image.Save(Console.OpenStandardOutput(), ImageFormat.Jpeg);
    }
  }
}
標準入出力のStreamを取得して画像の読み書きを行う
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging

Class Sample
  Shared Sub Main()
    ' 標準入力のStreamを取得して画像として読み込む
    Using image As New Bitmap(Console.OpenStandardInput())
      ' 画像を左右反転する
      image.RotateFlip(RotateFlipType.RotateNoneFlipX)

      ' 標準出力のStreamを取得して加工した画像を書き込む
      image.Save(Console.OpenStandardOutput(), ImageFormat.Jpeg)
    End Using
  End Sub
End Class
実行例
>sample.exe < sample.jpg > mirror.jpg

OpenStandardInput/OpenStandardOutput/OpenStandardErrorの各メソッドで得られる標準ストリームのStreamをラップすることにより、暗号化や圧縮・バッファリングなどの機能を付け加えることもできます。

次の例ではbase64コマンドに似たプログラムを実装しています。 CryptoStreamを使って標準入出力のStreamをラップすることにより、標準入力から読み込んだ内容をBASE64エンコード/デコードして標準出力に書き込んでいます。

標準入出力のStreamをラップしてBASE64エンコード/デコードの機能を付け加える
using System;
using System.IO;
using System.Security.Cryptography;

class Sample {
  static void Main(string[] args)
  {
    // コマンドライン引数に-dもしくは--decodeが指定されている場合はデコードを行う
    var decode = false;

    foreach (var arg in args) {
      if (arg == "-d" || arg  == "--decode")
        decode = true;
    }

    Stream input, output;

    if (decode) {
      // BASE64デコードする場合

      // 標準入力から読み込みを行い、FromBase64TransformによってBASE64デコードを行うCryptoStreamを入力元ストリームとする
      input = new CryptoStream(Console.OpenStandardInput(), new FromBase64Transform(), CryptoStreamMode.Read);

      // 標準出力を出力先ストリームとする
      output = Console.OpenStandardOutput();
    }
    else {
      // BASE64エンコードする場合

      // 標準入力を入力元ストリームとする
      input = Console.OpenStandardInput();

      // ToBase64TransformによってBASE64エンコードを行い、標準出力へ書き込むCryptoStreamを出力先ストリームとする
      output = new CryptoStream(Console.OpenStandardOutput(), new ToBase64Transform(), CryptoStreamMode.Write);
    }

    // 入力元ストリームの内容を出力先ストリームに'コピー'する
    // (コピーを行う際、CryptoStreamによってデコード/エンコード処理が行われる)
    input.CopyTo(output);

    output.Close();
  }
}
標準入出力のStreamをラップしてBASE64エンコード/デコードの機能を付け加える
Imports System
Imports System.IO
Imports System.Security.Cryptography

Class Sample
  Shared Sub Main(ByVal args As String())
    ' コマンドライン引数に-dもしくは--decodeが指定されている場合はデコードを行う
    Dim decode As Boolean = false

    For Each arg As String In args
      If arg = "-d" OrElse arg = "--decode" Then decode = True
    Next

    Dim input, output As Stream

    If decode Then
      ' BASE64デコードする場合

      ' 標準入力から読み込みを行い、FromBase64TransformによってBASE64デコードを行うCryptoStreamを入力元ストリームとする
      input = New CryptoStream(Console.OpenStandardInput(), New FromBase64Transform(), CryptoStreamMode.Read)

      ' 標準出力を出力先ストリームとする
      output = Console.OpenStandardOutput()
    Else
      ' BASE64エンコードする場合

      ' 標準入力を入力元ストリームとする
      input = Console.OpenStandardInput()

      ' ToBase64TransformによってBASE64エンコードを行い、標準出力へ書き込むCryptoStreamを出力先ストリームとする
      output = new CryptoStream(Console.OpenStandardOutput(), new ToBase64Transform(), CryptoStreamMode.Write)
    End If

    ' 入力元ストリームの内容を出力先ストリームに'コピー'する
    ' (コピーを行う際、CryptoStreamによってデコード/エンコード処理が行われる)
    input.CopyTo(output)

    output.Close()
  End Sub
End Class
実行例
>type sample.txt
Hello, world!

>type sample.txt | sample.exe
SGVsbG8sIHdvcmxkIQo=

>type sample.txt | sample.exe | sample.exe -d
Hello, world!

ストリームのラップについて、また暗号化や圧縮などのフォーマット変換、バッファリングなどの機能を付け加える方法等についてはストリームの基本とStreamクラス §.データフォーマットの変換やバッファリングなどの機能を追加するStream派生クラスも参照してください。

取得した標準ストリームを使う例として、コマンドラインオプションで標準入力とファイル入力を切り替える例を実装しているMD5ハッシュ文字列の作成 §.MD5クラスを使ってmd5sumコマンドを実装するもあわせてご覧ください。

標準ストリームのリダイレクト

SetIn/SetOut/SetErrorの各メソッドを使うと、実行時に標準ストリームを任意のTextReader/Writerへとリダイレクトすることができます。

標準ストリームのリダイレクトを行うと、Console.WriteLineやReadLineなどのメソッドの入出力先は、リダイレクト先として指定されたTextReader/Writerへと変更されます。

次の例ではSetOutメソッドを使って標準出力の出力先を実行時に開いたファイルに変更しています。

標準出力をStreamWriterにリダイレクトする
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // この内容はデフォルトの標準出力に書き込まれる
    Console.WriteLine("Hello, world!");

    // ファイルstdout.txtへ書き込むStreamWriterを作成する
    var writer = new StreamWriter("stdout.txt");

    // 書き込みの度にバッファをフラッシュさせるためにAutoFlushをtrueにする
    writer.AutoFlush = true;

    // 作成したStreamWriterを標準出力の出力先にする
    Console.SetOut(writer);

    // この内容はファイルstdout.txtに書き込まれる
    Console.WriteLine("こんにちは、世界!");
  }
}
標準出力をStreamWriterにリダイレクトする
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' この内容はデフォルトの標準出力に書き込まれる
    Console.WriteLine("Hello, world!")

    ' ファイルstdout.txtへ書き込むStreamWriterを作成する
    Dim writer As New StreamWriter("stdout.txt")

    ' 書き込みの度にバッファをフラッシュさせるためにAutoFlushをTrueにする
    writer.AutoFlush = True

    ' 作成したStreamWriterを標準出力の出力先にする
    Console.SetOut(writer)

    ' この内容はファイルstdout.txtに書き込まれる
    Console.WriteLine("こんにちは、世界!")
  End Sub
End Class
実行結果
>sample.exe
Hello, world!

>type stdout.txt
こんにちは、世界!

Console.In/Out/Errorプロパティから取得できるTextReader/Writerをリダイレクトする前に退避しておき、あとで再度リダイレクト先として設定することにより、一度リダイレクトした標準ストリームの入出力先を元の状態に戻すことができます。

リダイレクトした標準出力の出力先を元に戻す
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 初期状態での標準出力の出力先を退避しておく
    var stdout = Console.Out;

    // ファイルstdout.txtへ書き込むStreamWriterを作成する
    var writer = new StreamWriter("stdout.txt");

    // 書き込みの度にバッファをフラッシュさせるためにAutoFlushをtrueにする
    writer.AutoFlush = true;

    // 作成したStreamWriterを標準出力の出力先にする
    Console.SetOut(writer);

    // この内容はファイルstdout.txtに書き込まれる
    Console.WriteLine("Hello, world!");

    // 標準出力の出力先を元に戻す
    Console.SetOut(stdout);

    // この内容は(初期状態での)標準出力に書き込まれる
    Console.WriteLine("こんにちは、世界!");
  }
}
リダイレクトした標準出力の出力先を元に戻す
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 初期状態での標準出力の出力先を退避しておく
    Dim stdout As TextWriter = Console.Out

    ' ファイルstdout.txtへ書き込むStreamWriterを作成する
    Dim writer As New StreamWriter("stdout.txt")

    ' 書き込みの度にバッファをフラッシュさせるためにAutoFlushをTrueにする
    writer.AutoFlush = True

    ' 作成したStreamWriterを標準出力の出力先にする
    Console.SetOut(writer)

    ' この内容はファイルstdout.txtに書き込まれる
    Console.WriteLine("Hello, world!")

    ' 標準出力の出力先を元に戻す
    Console.SetOut(stdout)

    ' この内容は(初期状態での)標準出力に書き込まれる
    Console.WriteLine("こんにちは、世界!")
  End Sub
End Class
実行結果
>sample.exe
こんにちは、世界!

>type stdout.txt
Hello, world!

TextReader/Writerクラスは抽象クラスであるため、たいていの場合リダイレクト先の設定には派生クラスであるStreamReader/Writerを使うことになります。 TextReader/WriterおよびStreamReader/Writerの作成や扱い方についてはStreamReaderクラス・StreamWriterクラスを参照してください。

SetIn/SetOut/SetErrorメソッドではStreamをリダイレクト先として直接設定することはできません。 Streamをリダイレクト先として設定したい場合は、そのStreamをベースにしてStreamReader/Writerを作成する必要があります。 具体的な方法についてはStreamReaderクラス・StreamWriterクラス §.任意のStreamからの読み込み・書き込みを参照してください。

標準出力の破棄・空の標準入力 (NUL, /dev/null)

TextReader.NullフィールドTextWriter.Nullフィールドを標準ストリームのリダイレクト先として設定すると、標準ストリームをnullデバイス(NUL, /dev/null)にリダイレクトするのと同様の効果が得られます。 TextReader.Nullフィールドは空(長さ0)の標準入力として利用でき、TextWriter.Nullは空の標準出力として利用できます。

特にTextWriter.Nullは、標準出力のリダイレクト先として設定することにより、出力される内容を一切破棄する(何も出力させない)ことができます。

標準出力をTextWriter.Nullにリダイレクトして書き込まれた内容を破棄する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 標準出力の出力先をTextWriter.Nullに変更する
    // (標準出力をnullデバイスにリダイレクトした場合と似た効果となる)
    Console.SetOut(TextWriter.Null);

    // この内容はTextWriter.Nullに書き込まれる
    // (TextWriter.Nullは'なにもしない'ので、実際には'どこにも'/'なにも'出力されない)
    Console.WriteLine("Hello, world!");
  }
}
標準出力をTextWriter.Nullにリダイレクトして書き込まれた内容を破棄する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 標準出力の出力先をTextWriter.Nullに変更する
    ' (標準出力をnullデバイスにリダイレクトした場合と似た効果となる)
    Console.SetOut(TextWriter.Null)

    ' この内容はTextWriter.Nullに書き込まれる
    ' (TextWriter.Nullは'なにもしない'ので、実際には'どこにも'/'なにも'出力されない)
    Console.WriteLine("Hello, world!")
  End Sub
End Class

標準ストリームがリダイレクトされているか調べる

.NET Framework 4.5以降では、IsInputRedirected/IsOutputRedirected/IsErrorRedirectedの各プロパティを参照することにより、自プロセスの標準ストリームがリダイレクトされているかどうかを知ることができるようになっています。

これらのプロパティは、コマンドラインで標準ストリームのパイプ・リダイレクトを行った場合にtrueとなるほか、SetIn/SetOut/SetErrorメソッドによってリダイレクトを行った場合もtrueとなります。

標準ストリームがリダイレクトされているかどうかを調べる
using System;

class Sample {
  static void Main()
  {
    // 各標準ストリームがリダイレクトされているかどうかを調べる
    Console.WriteLine("IsInputRedirected:  {0}", Console.IsInputRedirected);
    Console.WriteLine("IsOutputRedirected: {0}", Console.IsOutputRedirected);
    Console.WriteLine("IsErrorRedirected:  {0}", Console.IsErrorRedirected);
  }
}
標準ストリームがリダイレクトされているかどうかを調べる
Imports System

Class Sample
  Shared Sub Main()
    ' 各標準ストリームがリダイレクトされているかどうかを調べる
    Console.WriteLine("IsInputRedirected:  {0}", Console.IsInputRedirected)
    Console.WriteLine("IsOutputRedirected: {0}", Console.IsOutputRedirected)
    Console.WriteLine("IsErrorRedirected:  {0}", Console.IsErrorRedirected)
  End Sub
End Class
実行結果
>sample.exe
IsInputRedirected:  False
IsOutputRedirected: False
IsErrorRedirected:  False

>type sample.txt | sample.exe
IsInputRedirected:  True
IsOutputRedirected: False
IsErrorRedirected:  False

>sample.exe | more
IsInputRedirected:  False
IsOutputRedirected: True
IsErrorRedirected:  False

>sample.exe < sample.txt
IsInputRedirected:  True
IsOutputRedirected: False
IsErrorRedirected:  False

>sample.exe > stdout.txt

>type stdout.txt
IsInputRedirected:  False
IsOutputRedirected: True
IsErrorRedirected:  False

>test.exe 2> stderr.txt
IsInputRedirected:  False
IsOutputRedirected: False
IsErrorRedirected:  True

これらのプロパティをチェックすることで標準出力の出力先がコンソールウィンドウかどうかを知ることができるため、リダイレクトされているときはConsole.ForegroundColor/BackgroundColorプロパティで文字色を変えたり、Console.CursorLeft/CursorTopプロパティでカーソルの位置を変えたりしないようにする、といったことができます。

.NET Framework 4.5より前のバージョンではこれらのプロパティは用意されないため、c# - How to detect if Console.In (stdin) has been redirected? - Stack Overflowで提示されているような方法を使って調べる必要があります。

標準ストリームのエンコーディング

InputEncoding/OutputEncodingプロパティを指定することで、標準入出力で使用されるエンコーディングを指定・変更することができます。

Consoleクラスでは、実行環境で用いられる文字コードに基づいて標準入出力のエンコーディングが設定されますが、これとは別のエンコーディングを使用する必要がある場合には、このプロパティを変更します。

このプロパティを指定することで、例えば標準入力には常にShift_JISを用い、標準出力にはUTF-8を用いる、といったことができます。

標準入出力で使用するエンコーディングを変更する
using System;
using System.IO;
using System.Text;

class Sample {
  static void Main()
  {
    // 標準入力のエンコーディングにShift_JISを用いる
    Console.InputEncoding = shift_jis;

    // 標準出力のエンコーディングにUTF-8を用いる
    Console.OutputEncoding = Encoding.UTF8;

    // 標準入力の内容すべてを読み込み標準出力に書き込む
    // (標準入出力を介してShift_JISからUTF-8への変換が行われる)
    Console.Out.Write(Console.In.ReadToEnd());
  }

  static readonly Encoding shift_jis =
#if NETFRAMEWORK
    Encoding.GetEncoding("shift_jis");
#else
    // `dotnet add sample.csproj package System.Text.Encoding.CodePages`
    CodePagesEncodingProvider.Instance.GetEncoding("shift_jis");
#endif
}
標準入出力で使用するエンコーディングを変更する
Imports System
Imports System.IO
Imports System.Text

Class Sample
  Shared Sub Main()
    ' 標準入力のエンコーディングにShift_JISを用いる
    Console.InputEncoding = shift_jis

    ' 標準出力のエンコーディングにUTF-8を用いる
    Console.OutputEncoding = Encoding.UTF8

    ' 標準入力の内容すべてを読み込み標準出力に書き込む
    ' (標準入出力を介してShift_JISからUTF-8への変換が行われる)
    Console.Out.Write(Console.In.ReadToEnd())
  End Sub

#If NETFRAMEWORK Then
  Shared ReadOnly shift_jis As Encoding = Encoding.GetEncoding("shift_jis")
#Else
  ' `dotnet add sample.vbproj package System.Text.Encoding.CodePages`
  Shared ReadOnly shift_jis As Encoding = CodePagesEncodingProvider.Instance.GetEncoding("shift_jis")
#End If
End Class
実行結果
>chcp
現在のコード ページ: 932

>type input.shiftjis.txt
こんにちは、世界!

Shift_JISのファイルinput.shiftjis.txtを標準入力に与える
UTF-8で出力される標準出力の内容をoutput.utf8.txtに書き込む
>sample.exe < input.shiftjis.txt > output.utf8.txt

>type output.utf8.txt
縺薙s縺ォ縺。縺ッ縲∽ク也阜・・

>chcp 65001
Active code page: 65001

>type output.utf8.txt
こんにちは、世界!

コンソールの文字コードを変更するコマンドchcpについてはMS-DOSコマンドプロンプトTips §.文字コードの変更を参照してください。

なお、ErrorEncodingプロパティは存在しないため、標準エラーのエンコーディングを指定・変更することはできません。 SetErrorメソッドを使えば任意のTextWriterを指定できるため、目的のエンコーディングを使用するStreamWriterを作成して標準エラーのリダイレクト先として指定する、といったことはできます。

OutputEncodingプロパティにUTF-8などのエンコーディングを指定すると、標準出力にBOM(Byte Order Mark)が出力される場合があります。 この動作はランタイムの種類や実行環境によって異なります。 詳細についてはEncodingクラスとBOMありなしの制御 §.Consoleクラスを参照してください。