テキストファイルの読み書き

ファイル操作の基礎

プログラムは単に画面に処理結果を表示するだけではありません。
例えば処理の結果をファイルに保存したり、プログラムの設定を外部ファイル化したりすることでより使いやすいプログラムにできます。

ファイルというのは他のプログラムからも使用されることがあるので、ファイル操作は比較的エラーの起きやすい処理です。
何らかの理由で読み書きに失敗した場合はエラー(例外)が発生します。

以下のサンプルコードはエラー処理は省いています。
エラーに適切に対処するには例外を参照してください。

usingに追加

まずコードの先頭に「using System.IO;」と「using System.Text;」を記述しておきます。
これは必須ではないのですが、コードの記述が簡便になるので記述しておきましょう。
「using System.Text;」は最初から記述されているかもしれません。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; //←これ
using System.Threading.Tasks;
using System.IO; //←これ

namespace ConsoleApplication1
{
//以下省略

それ以外のusing文はそのままで構いません。
余分なusingは削除しなくても支障はありません。

詳しくは名前空間を参照してください。

テキストファイルの書き込み

まずは適当なテキストファイルを作成し、文字列を書き込んでみます。


using System;
using System.IO;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = "test.txt";
            string text = "This is Test.\nあいうえお";

            //「path」に「text」を書き込み
            File.WriteAllText(path, text);

            Console.WriteLine("{0}に書き込みました。", path);
            Console.ReadLine();
        }
    }
}

C#のファイル読み書き機能はFileクラスで提供されています。
(System.IO.File)
ファイルを書き込みするにはFile.WriteAllTextメソッドを使用します。

上記コードはstring型変数textのテキストデータをそのまま「test.txt」というファイルに出力しています。
出力される場所はプログラム本体と同じ場所です。
Visual Studio上からの実行ならばファイルの場所は「プロジェクトフォルダ\プロジェクト名\bin\Debug\test.txt」です。
上記ファイルをメモ帳などで開いて中身を確認してみましょう。

指定のファイルが既に存在する場合は上書きされますので注意してください。

パスの指定はドライブ名から記述すれば絶対パスで指定できます。
ドライブ名がなければ相対パスとなります。

ちなみに相対パスで「ひとつ上のフォルダ」を指定するには以下のようにします。


//プログラム本体のひとつ上のフォルダに書き込み
File.WriteAllText(@"..\test.txt", "abcde");

先頭のアットマークはエスケープシーケンスの抑制記号です。
(エスケープシーケンス参照)

文字コードの指定

上記コードのテキストファイルはシステム規定の文字コードで書き込みされます。
文字コードを指定して書き込みする場合は第三引数にEncodingクラスを指定します。
(System.Text.Encoding)


string path = "test.txt";
string text = "This is Test.\nあいうえお";

//「UTF8」で書き込み
File.WriteAllText(path, text, Encoding.UTF8);

//「Shift-JIS」で書き込み
File.WriteAllText(path, text, Encoding.GetEncoding("shift-jis"));

//「Shift-JIS」で書き込み(数値指定)
File.WriteAllText(path, text, Encoding.GetEncoding(932));

Encodingクラスには最初から「UTF-7」「UTF-8」「Unicode(UTF-16)」「UTF-32」「ASCII」が用意されています。
これら以外の文字コードを使用する場合はEncoding.GetEncodingメソッドで指定します。
GetEncodingメソッドの引数には文字列か数値で文字コードを指定します。
具体的に指定できる値はマイクロソフトのヘルプを参照してください。
Encoding Class (System.Text) | Microsoft Doc

とりあえずは「UTF-8」「UTF-16」「Shift-JIS」あたりを指定しておけば大抵のテキストエディタで読み書きができると思います。

string配列、Listの書き込み

File.WriteAllLinesメソッドを使用すればstring型配列をテキストファイルに書き込むことができます。


string path = "test.txt";
string[] texts = new string[]
    { "This is Test.", "あいうえお" };

//string型配列をすべて書き込み
File.WriteAllLines(path, texts);

第二引数がstring型配列になる以外はWriteAllTextメソッドと同じです。
文字コードの指定も同様に可能です。

書き込まれるテキストは、配列の要素ごとに自動的に改行されます。

string型配列のほか、string型Listも引数に指定できます。

テキストファイルの読み込み

次にテキストファイルを読み込んでみます。


string path = "test.txt";
string text = "This is Test.\nあいうえお";

File.WriteAllText(path, text, Encoding.UTF8);

//ファイルの読み込み
string read = File.ReadAllText(path);

Console.WriteLine(read);
This is Test.
あいうえお

テキストファイルを出力した後に、そのファイルをすぐに読み込んでいます。
テキストファイルの読み込みにはFile.ReadAllTextメソッドを使用します。

文字コードを指定して読み込み

文字コードを指定してテキストファイルを読み込むにはReadAllTextメソッドの第二引数にEncodingクラスを指定します。
これはテキストファイルの書き込みの時と同じです。


//「Shift-JIS」のテキストファイルの読み込み
string read = File.ReadAllText("test.txt", Encoding.GetEncoding("shift-jis"));

他のプログラムで作成されたテキストファイルを読み込む場合などに文字コードが合っていないと文字化けを起こします。
その場合は文字コードを確認してください。

string型配列で取得

ReadAllLinesメソッドを使用すればテキストファイルをstring型配列で受け取ることができます。


string path = "test.txt";
string text = "This is Test.\nあいうえお";

File.WriteAllText(path, text, Encoding.UTF8);

//ファイルの読み込み
string[] reads = File.ReadAllLines(path);

foreach(var s in reads)
    Console.WriteLine(s);

戻り値がstring型配列になる以外はReadAllTextメソッドと同じです。
文字コードの指定も同様です。

ReadAllLinesメソッドは改行を区切りとして配列の各要素に格納して返します。

テキストファイルに追加

既存のテキストファイルを開き、ファイルの末尾に文字列を追加するにはFile.AppendAllTextメソッドを使用します。


string path = "test.txt";

string text = "This is Test.\nあいうえお";
string append = "\nAppended Text.";

//「path」に「text」を書き込み
File.WriteAllText(path, text);

Console.WriteLine("{0}に書き込みました。", path);

//「path」に「append」を追加
File.AppendAllText(path, append);

Console.WriteLine("{0}に追加しました。\n", path);

Console.WriteLine(File.ReadAllText(path));
test.txtに書き込みました。
test.txtに追加しました。

This is Test.
あいうえお
Appendet Text.

WriteAllTextメソッドがファイルの上書きなのに対して、AppendAllTextメソッドはファイルに追加するという動作に変わっただけです。
文字コードの指定なども同様に可能です。

指定のファイルが存在しない場合は新規に作成されます。

string配列、Listの追加

string型配列を一度に追加するにはFile.AppendAllLinesメソッドを使用します。
これもWriteAllLinesメソッドの動作がファイルの上書きから追加に変わっただけです。


string path = "test.txt";
string text = "This is Test.\nあいうえお";
string[] appends = new string[]
    { "aaa", "bbb", "ccc" };

//「path」に「text」を書き込み
File.WriteAllText(path, text);

Console.WriteLine("{0}に書き込みました。", path);

//「path」に「appends」を追加
File.AppendAllLines(path, appends);

Console.WriteLine("{0}に文字列を追加しました。\n", path);

Console.WriteLine(File.ReadAllText(path));
test.txtに書き込みました。
test.txtに追加しました。

This is Test.
あいうえおaaa
bbb
ccc