C#でテキストファイルを読み書きする方法|初心者向けにStreamReader・StreamWriter・Fileクラスを解説

はじめに

C#では、テキストファイルの読み込みや書き込みを簡単に行えます。設定ファイルを読み込む、ログを保存する、入力データをテキストとして出力するなど、テキストファイル操作は多くのアプリケーションで使われる基本的な処理です。

C#でテキストファイルを扱う方法はいくつかありますが、初心者がまず覚えておきたいのは、StreamReaderStreamWriterFileクラスです。

この記事では、C#でテキストファイルを読み書きする基本から、1行ずつ読み込む方法、ファイルに書き込む方法、追記する方法、文字コードの指定、よくあるエラーの対処法まで、初心者向けにわかりやすく解説します。

1. C#でテキストファイルを読み書きする基本

1-1. この記事でできるようになること

この記事を読むと、C#で次のようなテキストファイル操作ができるようになります。

テキストファイルを読み込む方法、テキストファイルに文字を書き込む方法、既存ファイルに追記する方法、ファイルが存在するか確認する方法、日本語の文字化けを防ぐ方法、例外処理を含めた安全なファイル操作の書き方などを理解できます。

たとえば、次のような処理をC#で書けるようになります。

C#
string text = File.ReadAllText("sample.txt");
Console.WriteLine(text);

また、入力した文字をファイルに保存する処理も簡単に書けます。

C#
File.WriteAllText("sample.txt", "こんにちは、C#のテキストファイル操作です。");

C#のテキストファイル操作は、最初は難しそうに見えますが、基本的な考え方を覚えればシンプルです。

1-2. C#のテキストファイル操作で使う主なクラス

C#でテキストファイルを読み書きするときによく使うクラスは、主に次の3つです。

StreamReaderは、テキストファイルを読み込むためのクラスです。1行ずつ読み込んだり、ファイル全体をまとめて読み込んだりできます。

StreamWriterは、テキストファイルに書き込むためのクラスです。新しくファイルを作成したり、既存ファイルに上書きしたり、追記したりできます。

Fileクラスは、ファイル操作を簡単に行うためのクラスです。短いコードで読み込み、書き込み、追記、存在確認などができます。

それぞれのクラスは、次のような場面で使われます。

C#
// Fileクラスでファイル全体を読み込む
string text = File.ReadAllText("sample.txt");

// StreamReaderで1行ずつ読み込む
using StreamReader reader = new StreamReader("sample.txt");

// StreamWriterで書き込む
using StreamWriter writer = new StreamWriter("sample.txt");

1-3. StreamReader・StreamWriter・Fileクラスの違い

StreamReaderStreamWriterFileクラスは、どれもテキストファイル操作に使えますが、役割が少し違います。

StreamReaderは読み込み専用です。特に、大きなファイルを1行ずつ読み込む場合に向いています。

StreamWriterは書き込み専用です。大量のテキストを順番に書き込む場合や、ログのように少しずつ出力したい場合に便利です。

Fileクラスは、短いコードで簡単にファイル操作をしたい場合に向いています。たとえば、ファイル全体を一度に読み込む、ファイル全体を一度に書き込む、といった処理に便利です。

C#
// Fileクラスは短く書ける
string text = File.ReadAllText("sample.txt");

// StreamReaderは細かく制御できる
using StreamReader reader = new StreamReader("sample.txt");
string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}

初心者のうちは、少量のテキストファイルならFileクラス、大きなファイルや1行ずつ処理したい場合はStreamReaderStreamWriterと覚えるとよいでしょう。

1-4. 初心者はどの方法から使えばよいか

初心者は、まずFileクラスから覚えるのがおすすめです。理由は、コードが短く、何をしているのか理解しやすいからです。

たとえば、テキストファイルを読み込むだけなら、次の1行で書けます。

C#
string text = File.ReadAllText("sample.txt");

書き込みも簡単です。

C#
File.WriteAllText("sample.txt", "保存したい文字列");

ただし、ファイルサイズが大きい場合や、1行ずつ処理したい場合はStreamReaderStreamWriterのほうが適しています。

学習の順番としては、まずFileクラスで基本を覚え、そのあとにStreamReaderStreamWriterを学ぶと理解しやすくなります。

2. 事前準備:テキストファイル操作に必要な知識

2-1. using System.IOを追加する

C#でテキストファイルを操作するには、System.IO名前空間を使います。

コードの先頭に次のように書きます。

C#
using System.IO;

System.IOには、ファイルやフォルダを扱うためのクラスが用意されています。FileStreamReaderStreamWriterなどもSystem.IOに含まれています。

また、文字コードを指定する場合はSystem.Textも使います。

C#
using System.IO;
using System.Text;

最近のC#では、プロジェクト設定によってはusingが自動で追加されている場合もあります。ただし、初心者のうちは必要なusingを明示しておくと、どの機能を使っているのか理解しやすくなります。

2-2. ファイルパスの指定方法を理解する

テキストファイルを読み書きするには、ファイルの場所を示す「ファイルパス」を指定します。

たとえば、次のコードではsample.txtというファイルを指定しています。

C#
string path = "sample.txt";

このようにファイル名だけを指定した場合、プログラムの実行場所を基準にファイルが探されます。

フォルダを含めて指定することもできます。

C#
string path = @"C:\Work\sample.txt";

C#では、Windowsのパスに含まれる\がエスケープ文字として扱われるため、文字列の前に@を付けると書きやすくなります。

C#
string path = @"C:\Users\Taro\Documents\memo.txt";

または、\を2つ重ねて書く方法もあります。

C#
string path = "C:\\Users\\Taro\\Documents\\memo.txt";

どちらも同じ意味ですが、ファイルパスを書くときは@を使う方法が読みやすくておすすめです。

2-3. 相対パスと絶対パスの違い

ファイルパスには、相対パスと絶対パスがあります。

絶対パスは、ドライブ名やルートからファイルの場所をすべて指定する方法です。

C#
string path = @"C:\Work\sample.txt";

相対パスは、プログラムの実行場所を基準にファイルを指定する方法です。

C#
string path = "sample.txt";

また、フォルダを指定することもできます。

C#
string path = @"data\sample.txt";

相対パスは便利ですが、実行場所によってファイルが見つからないことがあります。特にVisual Studioで実行している場合、思っているフォルダとは別の場所が基準になっていることがあります。

現在の実行フォルダを確認したい場合は、次のように書けます。

C#
Console.WriteLine(Directory.GetCurrentDirectory());

ファイルが見つからないときは、まずこの実行フォルダを確認すると原因を見つけやすくなります。

2-4. 文字コードと改行コードの基本

テキストファイルには、文字コードと改行コードがあります。

文字コードとは、文字をどのような形式で保存するかを決めるルールです。代表的な文字コードには、UTF-8Shift_JISがあります。

C#では、特に指定しない場合、UTF-8で扱われることが多いです。日本語を含むテキストファイルを扱う場合は、文字コードが合っていないと文字化けすることがあります。

たとえば、Shift_JISのファイルをUTF-8として読み込むと、日本語が正しく表示されない場合があります。

改行コードとは、行の終わりを表す文字のことです。Windowsでは主にCRLF、LinuxやmacOSでは主にLFが使われます。

C#で改行を含む文字列を扱う場合は、Environment.NewLineを使うと実行環境に合った改行コードを使えます。

C#
string text = "1行目" + Environment.NewLine + "2行目";

また、WriteLineを使うと自動的に改行が追加されます。

C#
using StreamWriter writer = new StreamWriter("sample.txt");
writer.WriteLine("1行目");
writer.WriteLine("2行目");

2-5. ファイルが存在しない場合の考え方

テキストファイルを読み込む場合、指定したファイルが存在しないとエラーになります。

C#
string text = File.ReadAllText("sample.txt");

このとき、sample.txtが存在しないとFileNotFoundExceptionなどの例外が発生します。

そのため、読み込む前にFile.Existsでファイルの存在を確認すると安全です。

C#
string path = "sample.txt";

if (File.Exists(path))
{
string text = File.ReadAllText(path);
Console.WriteLine(text);
}
else
{
Console.WriteLine("ファイルが見つかりません。");
}

一方で、書き込みの場合は、ファイルが存在しなければ自動的に作成されることがあります。

C#
File.WriteAllText("sample.txt", "新しいファイルを作成します。");

ただし、指定したフォルダが存在しない場合はエラーになります。たとえば、data\sample.txtに書き込む場合、dataフォルダが存在しないと失敗します。

必要に応じて、事前にフォルダを作成します。

C#
Directory.CreateDirectory("data");
File.WriteAllText(@"data\sample.txt", "フォルダ内に保存します。");

3. StreamReaderでテキストファイルを読み込む方法

3-1. StreamReaderとは

StreamReaderは、C#でテキストファイルを読み込むためのクラスです。

ファイルを先頭から順番に読み進めることができ、1行ずつ読み込む処理に向いています。大量のデータを扱う場合でも、ファイル全体を一度にメモリへ読み込まないため、効率よく処理できます。

基本的な使い方は次のとおりです。

C#
using StreamReader reader = new StreamReader("sample.txt");

string? line = reader.ReadLine();
Console.WriteLine(line);

ReadLineは、テキストファイルから1行読み込みます。読み込む行がなくなるとnullを返します。

3-2. テキストファイルを1行ずつ読み込む

StreamReaderでよく使うのが、テキストファイルを1行ずつ読み込む方法です。

C#
using System.IO;

string path = "sample.txt";

using StreamReader reader = new StreamReader(path);

string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}

このコードでは、ReadLineで1行ずつ読み込み、読み込んだ内容をコンソールに表示しています。

ReadLineは、次の行がある場合は文字列を返し、最後まで読み込むとnullを返します。そのため、while文を使ってファイルの最後まで繰り返し処理できます。

1行ずつ処理する方法は、ログファイル、CSV風のデータ、設定ファイルなどを扱うときに便利です。

たとえば、次のようなテキストファイルがあるとします。

Apple
Orange
Banana

このファイルを読み込むと、1行ずつAppleOrangeBananaが表示されます。

3-3. ReadToEndでファイル全体を読み込む

StreamReaderには、ファイル全体をまとめて読み込むReadToEndメソッドもあります。

C#
using System.IO;

string path = "sample.txt";

using StreamReader reader = new StreamReader(path);
string text = reader.ReadToEnd();

Console.WriteLine(text);

ReadToEndは、現在の位置からファイルの最後までを一度に読み込みます。

小さなテキストファイルであれば便利ですが、大きなファイルを扱う場合は注意が必要です。ファイル全体をメモリに読み込むため、サイズが大きいとメモリ使用量が増える可能性があります。

大きなファイルを扱う場合は、ReadLineで1行ずつ読み込む方法がおすすめです。

3-4. usingを使ってファイルを自動で閉じる

ファイルを読み込んだあとは、ファイルを閉じる必要があります。

StreamReaderを使う場合、usingを使うと処理が終わったときに自動でファイルを閉じてくれます。

C#
using StreamReader reader = new StreamReader("sample.txt");

string text = reader.ReadToEnd();
Console.WriteLine(text);

従来の書き方では、次のようにブロックで囲みます。

C#
using (StreamReader reader = new StreamReader("sample.txt"))
{
string text = reader.ReadToEnd();
Console.WriteLine(text);
}

どちらの書き方でも、usingの範囲を抜けるとStreamReaderが破棄され、ファイルが閉じられます。

ファイルを閉じ忘れると、別の処理で同じファイルを開けなくなることがあります。初心者のうちは、StreamReaderStreamWriterを使うときは必ずusingを使う、と覚えておきましょう。

3-5. 文字コードを指定して読み込む

日本語を含むテキストファイルを読み込む場合、文字コードを指定したいことがあります。

UTF-8で読み込む場合は、次のように書きます。

C#
using System.IO;
using System.Text;

string path = "sample.txt";

using StreamReader reader = new StreamReader(path, Encoding.UTF8);
string text = reader.ReadToEnd();

Console.WriteLine(text);

Shift_JISのファイルを読み込む場合は、環境によって追加設定が必要です。

.NET 6以降などでShift_JISを使う場合は、System.Text.Encoding.CodePagesパッケージを追加し、次のようにエンコーディングプロバイダーを登録します。

C#
using System.IO;
using System.Text;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

string path = "sample.txt";
Encoding sjis = Encoding.GetEncoding("shift_jis");

using StreamReader reader = new StreamReader(path, sjis);
string text = reader.ReadToEnd();

Console.WriteLine(text);

文字化けする場合は、ファイルの文字コードと、C#側で指定している文字コードが一致しているか確認しましょう。

3-6. StreamReaderでよくあるエラーと対処法

StreamReaderでよくあるエラーの1つは、ファイルが見つからないエラーです。

C#
using StreamReader reader = new StreamReader("sample.txt");

このとき、sample.txtが実行フォルダに存在しないとエラーになります。対処法として、File.Existsで確認します。

C#
string path = "sample.txt";

if (!File.Exists(path))
{
Console.WriteLine("ファイルが存在しません。");
return;
}

using StreamReader reader = new StreamReader(path);
string text = reader.ReadToEnd();
Console.WriteLine(text);

もう1つよくあるのが、ファイルを開いたままにしてしまう問題です。これはusingを使うことで防げます。

また、日本語が文字化けする場合は、文字コードの指定を確認します。

C#
using StreamReader reader = new StreamReader("sample.txt", Encoding.UTF8);

さらに、ファイルが別のアプリケーションで使用中の場合、読み込みに失敗することがあります。その場合は、ファイルを開いているアプリケーションを閉じるか、ファイルの使用状況を確認してください。

4. StreamWriterでテキストファイルに書き込む方法

4-1. StreamWriterとは

StreamWriterは、C#でテキストファイルに文字を書き込むためのクラスです。

新しいファイルを作成して書き込んだり、既存ファイルに上書きしたり、追記したりできます。WriteWriteLineを使って、文字列を順番にファイルへ出力します。

基本的な使い方は次のとおりです。

C#
using StreamWriter writer = new StreamWriter("sample.txt");

writer.WriteLine("こんにちは");
writer.WriteLine("C#でテキストファイルに書き込みます");

このコードを実行すると、sample.txtに2行の文字列が書き込まれます。

4-2. テキストファイルを新規作成して書き込む

StreamWriterを使ってテキストファイルを新規作成し、文字を書き込む例です。

C#
using System.IO;

string path = "sample.txt";

using StreamWriter writer = new StreamWriter(path);
writer.WriteLine("1行目のテキストです。");
writer.WriteLine("2行目のテキストです。");

指定したファイルが存在しない場合は、新しく作成されます。

すでに同じ名前のファイルが存在する場合は、標準では上書きされます。つまり、既存の内容は消えて、新しい内容に置き換わります。

そのため、既存の内容を残したい場合は、追記モードを使う必要があります。

4-3. WriteとWriteLineの違い

StreamWriterで文字を書き込むときは、WriteWriteLineを使います。

Writeは、文字列を書き込みますが、最後に改行を追加しません。

C#
using StreamWriter writer = new StreamWriter("sample.txt");

writer.Write("こんにちは");
writer.Write("C#");

この場合、ファイルには次のように書き込まれます。

こんにちはC#

一方、WriteLineは、文字列を書き込んだあとに改行を追加します。

C#
using StreamWriter writer = new StreamWriter("sample.txt");

writer.WriteLine("こんにちは");
writer.WriteLine("C#");

この場合、ファイルには次のように書き込まれます。

こんにちは
C#

文章やログを行単位で保存したい場合は、WriteLineを使うことが多いです。

4-4. 既存ファイルに上書きする方法

StreamWriterは、通常、既存ファイルに上書きします。

C#
string path = "sample.txt";

using StreamWriter writer = new StreamWriter(path);
writer.WriteLine("新しい内容です。");

このコードを実行すると、sample.txtに以前の内容があった場合でも、すべて消えて「新しい内容です。」だけになります。

明示的に上書きモードを指定することもできます。

C#
using StreamWriter writer = new StreamWriter("sample.txt", false);
writer.WriteLine("上書きします。");

第2引数にfalseを指定すると、上書きになります。省略した場合も基本的には上書きです。

重要なファイルを扱う場合は、上書きしてよいか注意しましょう。必要であれば、書き込む前にバックアップを作成する方法もあります。

C#
string path = "sample.txt";

if (File.Exists(path))
{
File.Copy(path, "sample_backup.txt", true);
}

using StreamWriter writer = new StreamWriter(path);
writer.WriteLine("新しい内容です。");

4-5. 既存ファイルに追記する方法

既存ファイルの内容を残したまま、末尾に文字を追加したい場合は追記モードを使います。

StreamWriterの第2引数にtrueを指定します。

C#
string path = "log.txt";

using StreamWriter writer = new StreamWriter(path, true);
writer.WriteLine("ログを追記します。");

このコードを実行すると、log.txtの末尾に新しい行が追加されます。

ログファイルのように、実行するたびに内容を追加したい場合に便利です。

C#
using StreamWriter writer = new StreamWriter("log.txt", true);
writer.WriteLine($"{DateTime.Now}: 処理を開始しました。");
writer.WriteLine($"{DateTime.Now}: 処理を終了しました。");

追記と上書きは間違えやすいので、trueなら追記、falseなら上書きと覚えておきましょう。

4-6. 文字コードを指定して書き込む

StreamWriterで文字コードを指定して書き込むこともできます。

UTF-8で書き込む例です。

C#
using System.IO;
using System.Text;

string path = "sample.txt";

using StreamWriter writer = new StreamWriter(path, false, Encoding.UTF8);
writer.WriteLine("UTF-8で書き込みます。");

第2引数は追記するかどうか、第3引数は文字コードです。

C#
new StreamWriter(path, false, Encoding.UTF8);

この場合、falseなので上書き、Encoding.UTF8なのでUTF-8で書き込みます。

追記しながらUTF-8で書き込む場合は、次のようにします。

C#
using StreamWriter writer = new StreamWriter(path, true, Encoding.UTF8);
writer.WriteLine("UTF-8で追記します。");

Shift_JISで書き込みたい場合は、読み込みのときと同じようにエンコーディングを指定します。

C#
using System.IO;
using System.Text;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

string path = "sample.txt";
Encoding sjis = Encoding.GetEncoding("shift_jis");

using StreamWriter writer = new StreamWriter(path, false, sjis);
writer.WriteLine("Shift_JISで書き込みます。");

4-7. StreamWriterでよくあるエラーと対処法

StreamWriterでよくあるエラーの1つは、書き込み先のフォルダが存在しないことです。

C#
using StreamWriter writer = new StreamWriter(@"data\sample.txt");

このとき、dataフォルダが存在しないとエラーになります。対処法として、事前にフォルダを作成します。

C#
Directory.CreateDirectory("data");

using StreamWriter writer = new StreamWriter(@"data\sample.txt");
writer.WriteLine("フォルダを作成してから書き込みます。");

また、ファイルが別のアプリケーションで開かれている場合、書き込みに失敗することがあります。たとえば、Excelやテキストエディタでファイルを開いたままにしている場合です。

さらに、アクセス権限がない場所に書き込もうとするとエラーになります。システムフォルダや他ユーザーのフォルダなどには注意が必要です。

例外処理を使うと、エラーが発生してもプログラムが突然終了するのを防げます。

C#
try
{
using StreamWriter writer = new StreamWriter("sample.txt");
writer.WriteLine("書き込みテスト");
}
catch (Exception ex)
{
Console.WriteLine("書き込み中にエラーが発生しました。");
Console.WriteLine(ex.Message);
}

5. Fileクラスで簡単に読み書きする方法

5-1. Fileクラスとは

Fileクラスは、C#でファイル操作を簡単に行うためのクラスです。

StreamReaderStreamWriterのようにインスタンスを作成しなくても、静的メソッドを使ってファイルの読み書きができます。

たとえば、テキストファイル全体を読み込む場合は次のように書けます。

C#
string text = File.ReadAllText("sample.txt");

ファイルに書き込む場合も簡単です。

C#
File.WriteAllText("sample.txt", "書き込む内容");

短いコードで処理できるため、初心者がC#でテキストファイルを扱うときに最初に覚える方法としておすすめです。

5-2. File.ReadAllTextでファイル全体を読み込む

File.ReadAllTextは、テキストファイル全体を1つの文字列として読み込むメソッドです。

C#
using System.IO;

string path = "sample.txt";

string text = File.ReadAllText(path);
Console.WriteLine(text);

ファイルの内容をまとめて取得したい場合に便利です。

文字コードを指定することもできます。

C#
using System.IO;
using System.Text;

string path = "sample.txt";

string text = File.ReadAllText(path, Encoding.UTF8);
Console.WriteLine(text);

ただし、ReadAllTextはファイル全体を一度にメモリへ読み込むため、大きなファイルには向いていません。大きなログファイルなどを扱う場合は、StreamReaderで1行ずつ読み込むほうが安全です。

5-3. File.ReadAllLinesで1行ずつ配列として読み込む

File.ReadAllLinesは、テキストファイルを行ごとに読み込み、文字列配列として取得するメソッドです。

C#
using System.IO;

string path = "sample.txt";

string[] lines = File.ReadAllLines(path);

foreach (string line in lines)
{
Console.WriteLine(line);
}

たとえば、ファイルの内容が次のようになっているとします。

佐藤
鈴木
田中

ReadAllLinesで読み込むと、次のような配列になります。

C#
lines[0] // 佐藤
lines[1] // 鈴木
lines[2] // 田中

行ごとにデータを処理したい場合に便利です。

文字コードを指定する場合は、次のように書きます。

C#
string[] lines = File.ReadAllLines("sample.txt", Encoding.UTF8);

ただし、ReadAllLinesも全行を一度に配列として読み込むため、大きなファイルの場合はメモリ使用量に注意が必要です。

5-4. File.WriteAllTextでファイルに書き込む

File.WriteAllTextは、指定したファイルに文字列を書き込むメソッドです。

C#
using System.IO;

string path = "sample.txt";
string text = "C#でテキストファイルに書き込みます。";

File.WriteAllText(path, text);

ファイルが存在しない場合は新しく作成されます。ファイルがすでに存在する場合は、内容が上書きされます。

複数行を書き込みたい場合は、改行を含めます。

C#
string text = "1行目" + Environment.NewLine + "2行目";

File.WriteAllText("sample.txt", text);

文字コードを指定して書き込むこともできます。

C#
File.WriteAllText("sample.txt", text, Encoding.UTF8);

WriteAllTextはとても便利ですが、上書きされる点に注意してください。既存の内容を残したい場合は、AppendAllTextを使います。

5-5. File.AppendAllTextでファイルに追記する

File.AppendAllTextは、既存ファイルの末尾に文字列を追加するメソッドです。

C#
using System.IO;

string path = "log.txt";

File.AppendAllText(path, "ログを追記します。" + Environment.NewLine);

ファイルが存在しない場合は、新しく作成されます。すでにファイルがある場合は、末尾に内容が追加されます。

ログ出力のような処理に便利です。

C#
string log = $"{DateTime.Now}: アプリケーションを起動しました。{Environment.NewLine}";

File.AppendAllText("log.txt", log);

文字コードを指定する場合は、次のように書きます。

C#
File.AppendAllText("log.txt", log, Encoding.UTF8);

追記する場合は、改行を忘れないようにしましょう。改行を入れないと、前の行の続きに文字がつながってしまいます。

5-6. File.Existsでファイルの存在を確認する

File.Existsは、指定したファイルが存在するかどうかを確認するメソッドです。

C#
using System.IO;

string path = "sample.txt";

if (File.Exists(path))
{
Console.WriteLine("ファイルがあります。");
}
else
{
Console.WriteLine("ファイルがありません。");
}

ファイルを読み込む前に存在確認をすると、エラーを防ぎやすくなります。

C#
string path = "sample.txt";

if (File.Exists(path))
{
string text = File.ReadAllText(path);
Console.WriteLine(text);
}
else
{
Console.WriteLine("読み込むファイルが見つかりません。");
}

ただし、File.Existsで存在を確認した直後に、別の処理によってファイルが削除される可能性もあります。そのため、実用的なプログラムでは例外処理も組み合わせるとより安全です。

5-7. Fileクラスを使うメリットと注意点

Fileクラスのメリットは、コードが短くてわかりやすいことです。

読み込みは次のように書けます。

C#
string text = File.ReadAllText("sample.txt");

書き込みも次のように書けます。

C#
File.WriteAllText("sample.txt", "保存する内容");

追記も簡単です。

C#
File.AppendAllText("sample.txt", "追記する内容" + Environment.NewLine);

一方で、注意点もあります。

ReadAllTextReadAllLinesはファイル全体を一度に読み込むため、大きなファイルではメモリを多く使います。

また、WriteAllTextは既存ファイルを上書きします。間違って重要なファイルを上書きしないように注意が必要です。

少量のテキストファイルを簡単に扱うならFileクラス、大きなファイルや細かい制御が必要な場合はStreamReaderStreamWriterを使うとよいでしょう。

6. StreamReader・StreamWriter・Fileクラスの使い分け

6-1. 少量のテキストならFileクラスが便利

少量のテキストファイルを読み書きするだけなら、Fileクラスが便利です。

たとえば、設定ファイルやメモ、簡単なデータ保存であれば、次のようなコードで十分です。

C#
File.WriteAllText("memo.txt", "メモを保存します。");

string text = File.ReadAllText("memo.txt");
Console.WriteLine(text);

Fileクラスを使うと、StreamReaderStreamWriterを明示的に作成する必要がないため、コードが短くなります。

初心者がC#でテキストファイル操作を学ぶときは、まずFile.ReadAllTextFile.WriteAllTextFile.AppendAllTextを覚えると実用的です。

6-2. 大きなファイルならStreamReader・StreamWriterが向いている

大きなテキストファイルを扱う場合は、StreamReaderStreamWriterが向いています。

File.ReadAllTextはファイル全体を一度に読み込みますが、StreamReaderなら1行ずつ読み込めます。

C#
using StreamReader reader = new StreamReader("large.txt");

string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}

この方法なら、ファイル全体を一度にメモリへ読み込まないため、大きなファイルでも扱いやすくなります。

書き込みの場合も、StreamWriterを使えば順番に書き込めます。

C#
using StreamWriter writer = new StreamWriter("output.txt");

for (int i = 1; i <= 1000; i++)
{
writer.WriteLine($"データ {i}");
}

大量のログやデータを扱う場合は、StreamReaderStreamWriterを使うのがおすすめです。

6-3. 1行ずつ処理したい場合の選び方

テキストファイルを1行ずつ処理したい場合は、ファイルサイズによって選び方が変わります。

ファイルが小さい場合は、File.ReadAllLinesで配列として読み込む方法が簡単です。

C#
string[] lines = File.ReadAllLines("sample.txt");

foreach (string line in lines)
{
Console.WriteLine(line);
}

一方、ファイルが大きい場合は、StreamReaderで1行ずつ読み込むほうが適しています。

C#
using StreamReader reader = new StreamReader("sample.txt");

string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}

初心者向けにまとめると、少量の行データならFile.ReadAllLines、大量の行データならStreamReader.ReadLineを使うとよいでしょう。

6-4. 上書き・追記・読み込み別のおすすめメソッド

C#でテキストファイルを扱うときは、目的に合わせてメソッドを選びます。

ファイル全体を読み込むなら、File.ReadAllTextが簡単です。

C#
string text = File.ReadAllText("sample.txt");

1行ずつ配列として読み込むなら、File.ReadAllLinesが便利です。

C#
string[] lines = File.ReadAllLines("sample.txt");

大きなファイルを1行ずつ読み込むなら、StreamReader.ReadLineを使います。

C#
using StreamReader reader = new StreamReader("sample.txt");

ファイルに上書きするなら、File.WriteAllTextまたはStreamWriterを使います。

C#
File.WriteAllText("sample.txt", "上書きします。");

ファイルに追記するなら、File.AppendAllTextまたは追記モードのStreamWriterを使います。

C#
File.AppendAllText("sample.txt", "追記します。" + Environment.NewLine);

ログのように何度も追記するなら、StreamWriterの追記モードも便利です。

C#
using StreamWriter writer = new StreamWriter("log.txt", true);
writer.WriteLine("ログを追記します。");

6-5. 初心者向けの使い分け早見表

C#のテキストファイル操作で迷ったときは、次のように選ぶとわかりやすいです。

やりたいことおすすめの方法
ファイル全体を読み込みたいFile.ReadAllText
ファイルを行ごとに配列で読みたいFile.ReadAllLines
大きなファイルを1行ずつ読みたいStreamReader.ReadLine
ファイルに上書きしたいFile.WriteAllText
ファイルに追記したいFile.AppendAllText
大量のデータを書き込みたいStreamWriter
文字コードを指定したいStreamReader / StreamWriter / Fileの文字コード指定
ファイルの存在を確認したいFile.Exists

初心者は、まずFileクラスで基本操作を覚え、その後で必要に応じてStreamReaderStreamWriterを使うとスムーズです。

7. 実践例:C#でテキストファイルを読み書きするサンプル

7-1. 入力した文字列をテキストファイルに保存する

コンソールから入力した文字列をテキストファイルに保存する例です。

C#
using System;
using System.IO;

Console.WriteLine("保存したい文字を入力してください。");
string? input = Console.ReadLine();

if (!string.IsNullOrEmpty(input))
{
File.WriteAllText("input.txt", input);
Console.WriteLine("ファイルに保存しました。");
}
else
{
Console.WriteLine("入力が空です。");
}

このコードでは、Console.ReadLineで入力を受け取り、File.WriteAllTextinput.txtに保存しています。

すでにinput.txtが存在する場合は、内容が上書きされます。

7-2. 保存したテキストファイルを読み込んで表示する

次に、保存したテキストファイルを読み込んで表示する例です。

C#
using System;
using System.IO;

string path = "input.txt";

if (File.Exists(path))
{
string text = File.ReadAllText(path);
Console.WriteLine("ファイルの内容:");
Console.WriteLine(text);
}
else
{
Console.WriteLine("ファイルが見つかりません。");
}

File.Existsでファイルの存在を確認してから読み込んでいるため、ファイルがない場合でもエラーになりにくいです。

保存と読み込みを組み合わせると、簡単なメモアプリのような処理を作れます。

7-3. ログファイルのように追記する

ログファイルのように、実行するたびに内容を追加する例です。

C#
using System;
using System.IO;

string path = "log.txt";

string log = $"{DateTime.Now}: 処理を実行しました。{Environment.NewLine}";

File.AppendAllText(path, log);

Console.WriteLine("ログを追記しました。");

AppendAllTextを使うことで、既存の内容を消さずに末尾へ追加できます。

StreamWriterを使う場合は、次のように書けます。

C#
using System;
using System.IO;

using StreamWriter writer = new StreamWriter("log.txt", true);

writer.WriteLine($"{DateTime.Now}: 処理を開始しました。");
writer.WriteLine($"{DateTime.Now}: 処理を終了しました。");

ログ出力では、日時を一緒に保存すると後から確認しやすくなります。

7-4. CSV風のテキストファイルを1行ずつ処理する

カンマ区切りのCSV風テキストファイルを1行ずつ読み込む例です。

たとえば、users.txtに次のような内容があるとします。

1,佐藤,Tokyo
2,鈴木,Osaka
3,田中,Nagoya

このファイルを読み込んで、カンマで分割します。

C#
using System;
using System.IO;

string path = "users.txt";

using StreamReader reader = new StreamReader(path);

string? line;
while ((line = reader.ReadLine()) != null)
{
string[] columns = line.Split(',');

string id = columns[0];
string name = columns[1];
string city = columns[2];

Console.WriteLine($"ID: {id}, 名前: {name}, 都市: {city}");
}

Split(',')を使うと、カンマで文字列を分割できます。

ただし、本格的なCSVでは、カンマを含む値やダブルクォーテーションを扱う必要があります。簡単な形式であれば上記の方法で十分ですが、複雑なCSVを扱う場合はCSV用ライブラリの利用も検討しましょう。

7-5. 例外処理を含めた実用的なコード例

実際のアプリケーションでは、ファイルが存在しない、アクセス権限がない、別のアプリが使用中など、さまざまな理由でエラーが起こる可能性があります。

そのため、例外処理を含めると安全です。

C#
using System;
using System.IO;
using System.Text;

string path = "sample.txt";

try
{
File.WriteAllText(path, "C#でテキストファイルを書き込みます。", Encoding.UTF8);

string text = File.ReadAllText(path, Encoding.UTF8);

Console.WriteLine("読み込んだ内容:");
Console.WriteLine(text);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("ファイルへのアクセス権限がありません。");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("指定されたフォルダが見つかりません。");
}
catch (FileNotFoundException)
{
Console.WriteLine("指定されたファイルが見つかりません。");
}
catch (IOException ex)
{
Console.WriteLine("ファイル操作中にエラーが発生しました。");
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("予期しないエラーが発生しました。");
Console.WriteLine(ex.Message);
}

例外処理を入れておくことで、エラーが発生したときに原因を表示し、プログラムを安全に終了できます。

特にファイル操作は、実行環境やファイルの状態に影響されやすいため、実用的なコードではtry-catchを使うことをおすすめします。

8. C#のテキストファイル操作でよくある疑問

8-1. ファイルが見つからないときはどうするか

C#でテキストファイルを読み込もうとして「ファイルが見つからない」と表示される場合、まずファイルパスを確認しましょう。

相対パスを使っている場合、基準になるのはプログラムの実行フォルダです。自分が思っているフォルダとは違う場所を見ている可能性があります。

現在の実行フォルダは、次のコードで確認できます。

C#
Console.WriteLine(Directory.GetCurrentDirectory());

ファイルの存在確認にはFile.Existsを使います。

C#
string path = "sample.txt";

if (!File.Exists(path))
{
Console.WriteLine("ファイルが見つかりません。");
return;
}

string text = File.ReadAllText(path);
Console.WriteLine(text);

また、フォルダが存在しない場合もエラーになります。書き込み前にフォルダを作成したい場合は、Directory.CreateDirectoryを使います。

C#
Directory.CreateDirectory("data");
File.WriteAllText(@"data\sample.txt", "保存内容");

8-2. 日本語が文字化けするときの原因

日本語が文字化けする主な原因は、文字コードの不一致です。

たとえば、ファイルがShift_JISで保存されているのに、C#側でUTF-8として読み込むと文字化けすることがあります。

UTF-8のファイルを読み込む場合は、次のように指定します。

C#
string text = File.ReadAllText("sample.txt", Encoding.UTF8);

Shift_JISの場合は、次のように指定します。

C#
using System.Text;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

Encoding sjis = Encoding.GetEncoding("shift_jis");
string text = File.ReadAllText("sample.txt", sjis);

文字化けしたときは、まずテキストファイルがどの文字コードで保存されているか確認しましょう。

Visual Studio Codeやメモ帳などのエディタでは、文字コードを確認・変更できる場合があります。

8-3. ファイルを開いたままになる原因

ファイルを開いたままになる原因として多いのは、StreamReaderStreamWriterを閉じていないことです。

次のようにusingを使えば、処理が終わったときに自動でファイルを閉じられます。

C#
using StreamReader reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();

または、従来の書き方でも問題ありません。

C#
using (StreamWriter writer = new StreamWriter("sample.txt"))
{
writer.WriteLine("書き込みます。");
}

usingを使わずにファイルを開いたままにすると、別の処理で同じファイルを読み書きできなくなることがあります。

ファイル操作では、基本的にusingを使うと覚えておくと安全です。

8-4. 上書きと追記の違い

上書きは、既存の内容を消して新しい内容に置き換えることです。

C#
File.WriteAllText("sample.txt", "新しい内容");

この場合、sample.txtに以前の内容があっても消えます。

追記は、既存の内容を残したまま末尾に新しい内容を追加することです。

C#
File.AppendAllText("sample.txt", "追加する内容" + Environment.NewLine);

StreamWriterの場合は、第2引数で上書きか追記かを指定します。

C#
// 上書き
using StreamWriter writer1 = new StreamWriter("sample.txt", false);

// 追記
using StreamWriter writer2 = new StreamWriter("sample.txt", true);

falseは上書き、trueは追記です。

重要なデータを扱う場合は、上書きと追記を間違えないように注意しましょう。

8-5. 改行が反映されないときの対処法

テキストファイルに書き込んだ内容が改行されない場合、改行コードが入っていない可能性があります。

Writeは改行を追加しません。

C#
writer.Write("1行目");
writer.Write("2行目");

この場合、次のようにつながって書き込まれます。

1行目2行目

改行したい場合は、WriteLineを使います。

C#
writer.WriteLine("1行目");
writer.WriteLine("2行目");

File.WriteAllTextFile.AppendAllTextを使う場合は、Environment.NewLineを追加します。

C#
File.AppendAllText("log.txt", "ログ1" + Environment.NewLine);
File.AppendAllText("log.txt", "ログ2" + Environment.NewLine);

複数行の文字列を作る場合も、Environment.NewLineを使うと環境に合った改行コードになります。

C#
string text = "1行目" + Environment.NewLine + "2行目";
File.WriteAllText("sample.txt", text);

8-6. .NET Frameworkと.NETで書き方は違うのか

基本的なC#のテキストファイル操作は、.NET Frameworkでも、.NET 6や.NET 8などの新しい.NETでも大きくは変わりません。

File.ReadAllTextFile.WriteAllTextStreamReaderStreamWriterなどの基本的な使い方はほぼ同じです。

C#
string text = File.ReadAllText("sample.txt");
File.WriteAllText("sample.txt", text);

ただし、文字コードの扱いには注意が必要です。

特にShift_JISなどのコードページを使う場合、新しい.NETではSystem.Text.Encoding.CodePagesパッケージを追加し、次のように登録が必要になることがあります。

C#
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

UTF-8のテキストファイルを扱うだけであれば、ほとんどの場合は同じように書けます。

初心者は、まずUTF-8で読み書きする方法を覚え、その後で必要に応じてShift_JISなどの文字コード指定を学ぶとよいでしょう。

まとめ

C#でテキストファイルを読み書きする方法には、主にStreamReaderStreamWriterFileクラスを使う方法があります。

少量のテキストファイルを簡単に読み書きしたい場合は、Fileクラスが便利です。

C#
string text = File.ReadAllText("sample.txt");
File.WriteAllText("sample.txt", "書き込む内容");
File.AppendAllText("sample.txt", "追記する内容" + Environment.NewLine);

大きなファイルを1行ずつ読み込みたい場合は、StreamReaderが向いています。

C#
using StreamReader reader = new StreamReader("sample.txt");

string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}

大量のデータを書き込んだり、ログのように追記したりする場合は、StreamWriterが便利です。

C#
using StreamWriter writer = new StreamWriter("log.txt", true);
writer.WriteLine($"{DateTime.Now}: ログを追記しました。");

また、ファイルが存在しない場合、文字化け、ファイルを開いたままになる問題などを防ぐために、File.Exists、文字コード指定、using、例外処理を適切に使うことが大切です。

C#のテキストファイル操作は、プログラムの基本として非常によく使われます。まずはFileクラスで簡単な読み書きを覚え、必要に応じてStreamReaderStreamWriterを使い分けると、実用的なファイル操作ができるようになります。