【C#】ファイル操作の基本|読み込み・書き込み・作成・削除を初心者向けに解説

はじめに

C#でアプリケーションを作るとき、ファイル操作はとてもよく使う基本機能です。たとえば、設定ファイルを読み込む、ログを保存する、CSVファイルを出力する、テキストファイルを作成する、といった処理は多くの場面で登場します。

C#では、FileクラスやStreamReaderStreamWriterなどを使うことで、ファイルの読み込み・書き込み・作成・削除・コピー・移動といった操作を簡単に実装できます。

この記事では、C#のファイル操作について、初心者向けに基本から実践例までわかりやすく解説します。

1. C#のファイル操作とは?初心者がまず押さえる基本

C#のファイル操作とは、プログラムからパソコン上のファイルにアクセスし、内容を読み取ったり、書き込んだり、作成・削除したりする処理のことです。

ファイル操作を理解すると、アプリケーションでデータを保存したり、外部ファイルを読み込んだりできるようになります。

1-1. C#でできる主なファイル操作

C#では、主に次のようなファイル操作ができます。

ファイルを読み込む処理では、テキストファイルやCSVファイルなどの内容を取得できます。

ファイルに書き込む処理では、文字列や複数行のデータを保存できます。

ファイルの作成では、新しいファイルをプログラムから生成できます。

ファイルの削除・コピー・移動では、既存ファイルを整理したり、バックアップを作成したりできます。

つまり、C#のファイル操作を覚えることで、外部データを扱うプログラムを作れるようになります。

1-2. ファイル操作で使う代表的なクラス

C#でファイルを扱うときによく使う代表的なクラスは次のとおりです。

Fileクラスは、ファイルの読み込み、書き込み、作成、削除、コピー、移動などを簡単に行えるクラスです。

Directoryクラスは、フォルダの作成、存在確認、削除などに使います。

Pathクラスは、ファイルパスを安全に組み立てたり、拡張子やファイル名を取得したりするときに使います。

StreamReaderは、ファイルを読み込むためのクラスです。大きなファイルを1行ずつ処理したい場合に向いています。

StreamWriterは、ファイルに書き込むためのクラスです。ログ出力や大量データの書き込みに向いています。

1-3. System.IO名前空間の使い方

C#でファイル操作を行うには、基本的にSystem.IO名前空間を使います。

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

C#
using System.IO;

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

C#
using System.Text;

たとえば、テキストファイルを読み込む基本的なコードは次のようになります。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string text = File.ReadAllText("sample.txt");
Console.WriteLine(text);
}
}

System.IOを使うことで、C#でファイルを簡単に扱えるようになります。

1-4. ファイル操作の基本的な流れ

C#のファイル操作は、基本的に次の流れで考えるとわかりやすいです。

まず、対象となるファイルパスを決めます。

次に、ファイルが存在するか確認します。

その後、読み込み、書き込み、削除、コピーなど必要な処理を行います。

最後に、必要であれば例外処理を行い、エラーに備えます。

たとえば、ファイルを読み込む場合は次のような流れになります。

C#
string path = "sample.txt";

if (File.Exists(path))
{
string text = File.ReadAllText(path);
Console.WriteLine(text);
}
else
{
Console.WriteLine("ファイルが存在しません。");
}

ファイル操作では、ファイルが存在しない、アクセス権限がない、別のプログラムが使用中などのエラーが発生する可能性があります。そのため、存在確認や例外処理を組み合わせることが重要です。

2. C#でファイルを読み込む方法

C#でファイルを読み込む方法はいくつかあります。小さなテキストファイルならFile.ReadAllTextFile.ReadAllLinesが簡単です。

一方、大きなファイルを扱う場合は、StreamReaderを使って1行ずつ読み込む方法が適しています。

2-1. File.ReadAllTextでテキストファイルを読み込む

File.ReadAllTextは、ファイルの内容をすべて文字列として読み込むメソッドです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "sample.txt";

string text = File.ReadAllText(path);

Console.WriteLine(text);
}
}

このコードでは、sample.txtの内容をすべて読み込み、コンソールに表示しています。

File.ReadAllTextは書き方がシンプルなので、C#のファイル読み込みを初めて学ぶ場合におすすめです。

ただし、ファイル全体を一度にメモリへ読み込むため、非常に大きなファイルには向いていません。

2-2. File.ReadAllLinesで1行ずつ読み込む

File.ReadAllLinesを使うと、ファイルの内容を行単位で配列として読み込めます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "sample.txt";

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

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

ReadAllLinesは、1行ずつ処理したい場合に便利です。

たとえば、設定ファイルやCSVファイルのように、行ごとに意味があるファイルを読み込むときによく使います。

2-3. StreamReaderで大きなファイルを読み込む

大きなファイルを扱う場合は、StreamReaderを使うのがおすすめです。

StreamReaderを使うと、ファイル全体を一度に読み込まず、1行ずつ順番に処理できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "large.txt";

using (StreamReader reader = new StreamReader(path))
{
string? line;

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

using文を使うことで、ファイルの読み込みが終わったあとに自動でリソースが解放されます。

ファイル操作では、読み込み後にファイルを閉じることが重要です。usingを使えば閉じ忘れを防げます。

2-4. 文字化けを防ぐエンコーディング指定

日本語のファイルを読み込むときに文字化けする場合は、文字コードが原因であることが多いです。

文字コードを指定するには、Encodingを使います。

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

class Program
{
static void Main()
{
string path = "sample.txt";

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

Console.WriteLine(text);
}
}

UTF-8のファイルを読み込む場合は、Encoding.UTF8を指定します。

Shift_JISのファイルを扱う場合は、環境によって追加設定が必要になることがあります。

C#
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

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

日本語のテキストファイルをC#で読み込む場合は、ファイルの文字コードとプログラム側の指定を合わせることが大切です。

3. C#でファイルに書き込む方法

C#では、ファイルに文字列や複数行のデータを書き込むことも簡単にできます。

基本的には、File.WriteAllTextFile.WriteAllLinesStreamWriterを使います。

3-1. File.WriteAllTextでファイルに書き込む

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

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "output.txt";
string content = "こんにちは、C#のファイル操作です。";

File.WriteAllText(path, content);

Console.WriteLine("ファイルに書き込みました。");
}
}

このコードを実行すると、output.txtが作成され、指定した文字列が書き込まれます。

すでに同じ名前のファイルが存在する場合、内容は上書きされます。

3-2. File.WriteAllLinesで複数行を書き込む

複数行のテキストを書き込む場合は、File.WriteAllLinesが便利です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "lines.txt";

string[] lines =
{
"1行目のテキスト",
"2行目のテキスト",
"3行目のテキスト"
};

File.WriteAllLines(path, lines);

Console.WriteLine("複数行を書き込みました。");
}
}

配列やリストの内容をそのまま行単位で保存できるため、ログやCSVの出力にも利用できます。

3-3. StreamWriterで効率よく書き込む

大量のデータを書き込む場合は、StreamWriterを使うと効率的です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "data.txt";

using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine("1行目");
writer.WriteLine("2行目");
writer.WriteLine("3行目");
}

Console.WriteLine("書き込みが完了しました。");
}
}

StreamWriterでは、WriteLineを使って1行ずつ書き込めます。

using文を使うことで、書き込みが終わったあとにファイルが正しく閉じられます。

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

既存ファイルに追記したい場合は、File.AppendAllTextを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "log.txt";

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

Console.WriteLine("追記しました。");
}
}

AppendAllTextは、ファイルが存在する場合は末尾に追記し、存在しない場合は新しくファイルを作成します。

StreamWriterで追記する場合は、コンストラクターの第2引数にtrueを指定します。

C#
using (StreamWriter writer = new StreamWriter("log.txt", true))
{
writer.WriteLine("追記するログです。");
}

ログファイルのように、既存の内容を残したまま新しいデータを追加したい場合に便利です。

4. C#でファイルを作成する方法

C#でファイルを作成するには、File.CreateFile.WriteAllTextなどを使います。

空のファイルを作るだけならFile.Create、内容を書き込みながら作成するならWriteAllTextが使いやすいです。

4-1. File.Createで新規ファイルを作成する

File.Createを使うと、新しいファイルを作成できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "newfile.txt";

using (FileStream fs = File.Create(path))
{
}

Console.WriteLine("ファイルを作成しました。");
}
}

File.CreateFileStreamを返します。そのため、作成後はファイルを閉じる必要があります。

using文を使えば、自動的にファイルが閉じられます。

4-2. ファイルが存在するか確認して作成する

すでにファイルが存在する場合に上書きしたくないときは、File.Existsで確認してから作成します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "sample.txt";

if (!File.Exists(path))
{
using (FileStream fs = File.Create(path))
{
}

Console.WriteLine("ファイルを作成しました。");
}
else
{
Console.WriteLine("ファイルはすでに存在します。");
}
}
}

ファイル操作では、意図しない上書きを防ぐために、存在確認を行うことが大切です。

4-3. フォルダが存在しない場合の対処

指定したフォルダが存在しない状態でファイルを作成しようとすると、エラーになります。

そのため、必要に応じてDirectory.CreateDirectoryでフォルダを作成します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = "data";
string filePath = Path.Combine(folderPath, "sample.txt");

if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}

File.WriteAllText(filePath, "フォルダ内にファイルを作成しました。");

Console.WriteLine("完了しました。");
}
}

Directory.CreateDirectoryは、すでにフォルダが存在していてもエラーになりません。

そのため、フォルダ作成処理ではよく使われます。

4-4. ファイル作成時に注意すべきポイント

ファイルを作成するときは、いくつか注意点があります。

まず、同じ名前のファイルがすでに存在する場合、メソッドによっては上書きされることがあります。

次に、保存先フォルダが存在しない場合はエラーになります。

また、アクセス権限がない場所にファイルを作ろうとすると例外が発生します。

たとえば、システムフォルダや他ユーザーのフォルダに書き込もうとすると、権限エラーになることがあります。

安全にファイルを作成するには、次のように存在確認や例外処理を組み合わせるのがおすすめです。

C#
try
{
string path = "sample.txt";

if (!File.Exists(path))
{
File.WriteAllText(path, "新規作成しました。");
}
}
catch (Exception ex)
{
Console.WriteLine("エラーが発生しました: " + ex.Message);
}

5. C#でファイルを削除・移動・コピーする方法

C#では、ファイルの削除、コピー、移動、名前変更も簡単に行えます。

主に使うメソッドは、File.DeleteFile.CopyFile.Moveです。

5-1. File.Deleteでファイルを削除する

ファイルを削除するには、File.Deleteを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "delete.txt";

if (File.Exists(path))
{
File.Delete(path);
Console.WriteLine("ファイルを削除しました。");
}
else
{
Console.WriteLine("ファイルが存在しません。");
}
}
}

File.Deleteは、指定したファイルを削除します。

削除したファイルは基本的に元に戻せないため、実行前に対象ファイルをよく確認しましょう。

5-2. File.Copyでファイルをコピーする

ファイルをコピーするには、File.Copyを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string sourcePath = "original.txt";
string destinationPath = "copy.txt";

if (File.Exists(sourcePath))
{
File.Copy(sourcePath, destinationPath, true);
Console.WriteLine("ファイルをコピーしました。");
}
}
}

第3引数にtrueを指定すると、コピー先に同名ファイルが存在しても上書きします。

上書きしたくない場合は、falseを指定するか、第3引数を省略します。

C#
File.Copy(sourcePath, destinationPath);

コピー先に同名ファイルがある場合は例外が発生するため、事前に存在確認を行うと安全です。

5-3. File.Moveでファイルを移動・名前変更する

ファイルを移動するには、File.Moveを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string sourcePath = "old.txt";
string destinationPath = "folder/new.txt";

if (File.Exists(sourcePath))
{
File.Move(sourcePath, destinationPath);
Console.WriteLine("ファイルを移動しました。");
}
}
}

File.Moveは、ファイルの移動だけでなく、名前変更にも使えます。

C#
File.Move("oldname.txt", "newname.txt");

同じフォルダ内で移動先の名前を変えれば、ファイル名の変更になります。

5-4. 削除・移動・コピー前の存在確認

ファイル操作でエラーを防ぐには、処理前に存在確認を行うことが重要です。

C#
string path = "sample.txt";

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

コピーや移動では、コピー元だけでなくコピー先の確認も大切です。

C#
string source = "source.txt";
string dest = "dest.txt";

if (File.Exists(source) && !File.Exists(dest))
{
File.Copy(source, dest);
}

ファイル操作は、対象ファイルの状態によって結果が変わります。存在確認を習慣にすると、予期しないエラーを減らせます。

6. ファイルパスの指定方法とよくあるつまずき

C#のファイル操作で初心者がつまずきやすいのが、ファイルパスの指定です。

ファイルパスには、絶対パスと相対パスがあります。また、Windowsではバックスラッシュを使うため、エスケープにも注意が必要です。

6-1. 絶対パスと相対パスの違い

絶対パスとは、ドライブ名やルートから始まる完全なパスのことです。

C#
string path = @"C:\Users\user\Documents\sample.txt";

相対パスとは、現在の実行位置を基準にしたパスです。

C#
string path = "sample.txt";

相対パスの場合、プログラムの実行場所によって参照先が変わることがあります。

そのため、ファイルが見つからない場合は、現在の実行フォルダを確認すると原因がわかることがあります。

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

6-2. パスの区切り文字とエスケープ

Windowsのパスでは、区切り文字に\を使います。

しかし、C#の文字列では\はエスケープ文字として扱われます。

そのため、通常の文字列では次のように\\と書く必要があります。

C#
string path = "C:\\Users\\user\\Documents\\sample.txt";

または、文字列の前に@を付けることで、そのまま書けます。

C#
string path = @"C:\Users\user\Documents\sample.txt";

初心者には、パスを書くときは@を付ける方法がわかりやすいです。

6-3. Path.Combineで安全にパスを作る

ファイルパスを文字列連結で作ると、区切り文字の不足や重複が起こりやすくなります。

そのため、C#ではPath.Combineを使うのがおすすめです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folder = "data";
string fileName = "sample.txt";

string path = Path.Combine(folder, fileName);

Console.WriteLine(path);
}
}

Path.Combineを使うと、環境に合わせて正しい区切り文字でパスを作成できます。

フォルダ名やファイル名を組み合わせるときは、文字列連結よりもPath.Combineを使いましょう。

6-4. 実行ファイルの場所を基準にする方法

実行ファイルの場所を基準にファイルパスを作りたい場合は、AppContext.BaseDirectoryを使います。

C#
string basePath = AppContext.BaseDirectory;
string filePath = Path.Combine(basePath, "sample.txt");

Console.WriteLine(filePath);

AppContext.BaseDirectoryは、アプリケーションの実行場所を取得できます。

設定ファイルやテンプレートファイルを実行ファイルと同じ場所に置く場合に便利です。

C#
string configPath = Path.Combine(AppContext.BaseDirectory, "config.json");

相対パスでファイルが見つからない場合は、基準となるフォルダがどこなのかを確認することが大切です。

7. C#のファイル操作で発生しやすいエラーと対処法

C#でファイル操作を行うと、さまざまなエラーが発生することがあります。

よくある原因は、ファイルが存在しない、アクセス権限がない、ファイルが別のプログラムで使用中、パスが間違っているなどです。

7-1. ファイルが見つからないエラー

存在しないファイルを読み込もうとすると、エラーが発生します。

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

このようなエラーを防ぐには、File.Existsで確認してから読み込みます。

C#
string path = "sample.txt";

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

ファイルが見つからない場合は、ファイル名、拡張子、パス、実行フォルダを確認しましょう。

7-2. アクセス権限がないエラー

アクセス権限がない場所にファイルを書き込もうとすると、例外が発生します。

たとえば、管理者権限が必要なフォルダや、読み取り専用の場所に書き込む場合です。

C#
try
{
File.WriteAllText(@"C:\Windows\sample.txt", "test");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("アクセス権限がありません: " + ex.Message);
}

対処法としては、書き込み可能なフォルダを指定する、アプリケーションの権限を確認する、読み取り専用属性を確認するなどがあります。

通常は、ユーザーのドキュメントフォルダやアプリケーション用のデータフォルダなど、書き込みが許可された場所を使いましょう。

7-3. ファイルが使用中のエラー

別のプログラムがファイルを開いている場合や、自分のプログラム内でファイルを閉じ忘れている場合、ファイルが使用中のエラーになることがあります。

C#
try
{
File.Delete("sample.txt");
}
catch (IOException ex)
{
Console.WriteLine("ファイルが使用中です: " + ex.Message);
}

このエラーを防ぐには、using文を使ってファイルを正しく閉じることが大切です。

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

using文を使えば、処理が終わったあとに自動でリソースが解放されます。

7-4. try-catchで例外処理を行う

ファイル操作では、予期しないエラーが発生する可能性があります。

そのため、必要に応じてtry-catchで例外処理を行います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "sample.txt";

try
{
string text = File.ReadAllText(path);
Console.WriteLine(text);
}
catch (FileNotFoundException)
{
Console.WriteLine("ファイルが見つかりません。");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("アクセス権限がありません。");
}
catch (IOException ex)
{
Console.WriteLine("入出力エラーが発生しました: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("予期しないエラーです: " + ex.Message);
}
}
}

例外処理を入れておくことで、エラーが発生してもプログラムが突然終了するのを防げます。

8. 実践例で学ぶC#ファイル操作

ここからは、実際によく使うC#のファイル操作を例で見ていきます。

読み込み、保存、ログ追記、CSVファイルの読み書きは、実務でもよく使われる処理です。

8-1. テキストファイルを読み込んで画面に表示する

次の例では、テキストファイルを読み込んで、内容をコンソールに表示します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "message.txt";

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

File.Existsでファイルの存在を確認しているため、ファイルがない場合でも安全に処理できます。

8-2. 入力内容をファイルに保存する

次の例では、ユーザーがコンソールに入力した内容をファイルに保存します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
Console.WriteLine("保存したい文章を入力してください。");
string? input = Console.ReadLine();

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

ユーザーの入力内容を保存したい場合は、Console.ReadLineFile.WriteAllTextを組み合わせると簡単です。

8-3. ログファイルに追記する

アプリケーションでは、処理結果やエラー内容をログファイルに残すことがあります。

ログは既存の内容を消さず、末尾に追記するのが一般的です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string logPath = "app.log";

string log = $"{DateTime.Now}: アプリケーションを開始しました。";

File.AppendAllText(logPath, log + Environment.NewLine);

Console.WriteLine("ログを出力しました。");
}
}

DateTime.Nowを使うことで、ログに日時を含められます。

エラー内容をログに残す場合は、次のように書けます。

C#
try
{
string text = File.ReadAllText("sample.txt");
}
catch (Exception ex)
{
File.AppendAllText("error.log", $"{DateTime.Now}: {ex.Message}{Environment.NewLine}");
}

ログファイルへの追記は、C#のファイル操作で特によく使われる実践的な処理です。

8-4. CSVファイルを読み書きする

CSVファイルは、データをカンマ区切りで保存する形式です。

まず、CSVファイルを書き込む例です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "users.csv";

string[] lines =
{
"Id,Name,Age",
"1,Tanaka,25",
"2,Suzuki,30",
"3,Sato,28"
};

File.WriteAllLines(path, lines);

Console.WriteLine("CSVファイルを作成しました。");
}
}

次に、CSVファイルを読み込む例です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = "users.csv";

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

foreach (string line in lines)
{
string[] columns = line.Split(',');

foreach (string column in columns)
{
Console.Write(column + " ");
}

Console.WriteLine();
}
}
}
}

単純なCSVであればSplit(',')で分割できます。

ただし、値の中にカンマやダブルクォーテーションが含まれる本格的なCSVを扱う場合は、CSV専用のライブラリを使う方が安全です。

9. C#ファイル操作の注意点とベストプラクティス

C#でファイル操作を行うときは、ただ動けばよいというわけではありません。

安全性、効率、保守性を考えて実装することが大切です。

9-1. using文でリソースを正しく解放する

StreamReaderStreamWriterFileStreamを使う場合は、using文でリソースを解放しましょう。

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

using文を使わないと、ファイルが開かれたままになり、削除や上書きができなくなることがあります。

C#では、次のような書き方もできます。

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

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

ファイルを扱うクラスは、使い終わったら必ず閉じるという意識を持ちましょう。

9-2. 大きなファイルは一括読み込みを避ける

File.ReadAllTextFile.ReadAllLinesは便利ですが、大きなファイルを一括で読み込むとメモリを大量に使います。

大きなログファイルやCSVファイルを扱う場合は、StreamReaderで1行ずつ読み込むのがおすすめです。

C#
using (StreamReader reader = new StreamReader("large.csv"))
{
string? line;

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

ファイルサイズが小さい場合はFileクラス、大きい場合はStreamReaderStreamWriterと考えるとわかりやすいです。

9-3. 非同期処理でファイル操作を行う

ファイル操作に時間がかかる場合、非同期処理を使うことでアプリケーションの応答性を保てます。

C#では、ReadAllTextAsyncWriteAllTextAsyncなどの非同期メソッドが用意されています。

C#
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
static async Task Main()
{
string path = "sample.txt";

string text = await File.ReadAllTextAsync(path);

Console.WriteLine(text);
}
}

書き込みも非同期で行えます。

C#
await File.WriteAllTextAsync("output.txt", "非同期で書き込みました。");

デスクトップアプリやWebアプリでは、ファイル操作を非同期化することで処理待ちによる停止を減らせます。

9-4. セキュリティと入力値チェックに注意する

ユーザーが入力したファイル名やパスをそのまま使うと、意図しないファイルにアクセスされる可能性があります。

たとえば、ユーザー入力で../のような相対パスを指定されると、想定外の場所のファイルにアクセスする危険があります。

そのため、ユーザー入力を使ってファイル操作をする場合は、入力値をチェックしましょう。

C#
string fileName = "sample.txt";

if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
{
Console.WriteLine("使用できない文字が含まれています。");
}
else
{
Console.WriteLine("有効なファイル名です。");
}

また、重要なファイルを削除・上書きしないように、保存先フォルダを固定したり、許可された拡張子だけを扱ったりすることも大切です。

安全なファイル操作を行うためには、パス、ファイル名、拡張子、アクセス権限を意識しましょう。

10. C#のファイル操作に関するよくある質問

ここでは、C#のファイル操作で初心者が疑問に思いやすいポイントをまとめます。

10-1. FileクラスとStreamReaderの違いは?

Fileクラスは、ファイル全体を簡単に読み書きしたいときに便利です。

たとえば、File.ReadAllTextFile.WriteAllTextを使えば、少ないコードでファイル操作ができます。

一方、StreamReaderは、ファイルを少しずつ読み込むためのクラスです。

大きなファイルを1行ずつ処理したい場合や、メモリ使用量を抑えたい場合に向いています。

小さなファイルならFileクラス、大きなファイルならStreamReaderを使うと考えるとわかりやすいです。

10-2. ファイルが存在しない場合はどうする?

ファイルが存在しない可能性がある場合は、File.Existsで確認します。

C#
string path = "sample.txt";

if (File.Exists(path))
{
string text = File.ReadAllText(path);
}
else
{
Console.WriteLine("ファイルが存在しません。");
}

書き込みの場合は、File.WriteAllTextを使うと、ファイルが存在しなければ新しく作成されます。

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

ただし、既存ファイルがある場合は上書きされるため注意しましょう。

10-3. 上書きせずに追記するには?

上書きせずに追記したい場合は、File.AppendAllTextを使います。

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

また、StreamWriterで追記する場合は、第2引数にtrueを指定します。

C#
using (StreamWriter writer = new StreamWriter("log.txt", true))
{
writer.WriteLine("追記する内容");
}

ログファイルのように、過去の内容を残したい場合は追記を使いましょう。

10-4. 日本語が文字化けする原因は?

日本語が文字化けする主な原因は、ファイルの文字コードとC#側で指定しているエンコーディングが一致していないことです。

たとえば、ファイルがUTF-8なのにShift_JISとして読み込むと、文字化けすることがあります。

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

C#
using System.Text;

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

Shift_JISのファイルを扱う場合は、次のように指定します。

C#
using System.Text;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

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

文字化けを防ぐには、ファイルの文字コードを確認し、読み込み・書き込み時に同じ文字コードを指定することが大切です。

まとめ

C#のファイル操作は、アプリケーション開発でよく使う基本的な処理です。

ファイルを読み込むには、File.ReadAllTextFile.ReadAllLinesStreamReaderを使います。

ファイルに書き込むには、File.WriteAllTextFile.WriteAllLinesStreamWriterを使います。

既存ファイルに追記する場合は、File.AppendAllTextStreamWriterの追記モードを使います。

ファイルを作成・削除・コピー・移動する場合は、File.CreateFile.DeleteFile.CopyFile.Moveが便利です。

また、ファイルパスを扱うときは、Path.Combineを使うと安全です。フォルダが存在しない場合は、Directory.CreateDirectoryで作成できます。

C#でファイルを扱うときは、存在確認、例外処理、文字コード、リソース解放に注意することが大切です。

まずは小さなテキストファイルの読み書きから始めて、慣れてきたらログ出力やCSVファイルの読み書きにも挑戦してみましょう。