テキストファイルの読み書き
ファイル操作の基礎
プログラムは単に画面に処理結果を表示するだけではありません。
例えば処理の結果をファイルに保存したり、プログラムの設定を外部ファイル化したりすることでより使いやすいプログラムにできます。
ファイルというのは他のプログラムからも使用されることがあるので、ファイル操作は比較的エラーの起きやすい処理です。
何らかの理由で読み書きに失敗した場合は実行時エラー(例外)になります。
以下のサンプルコードはエラー処理は省いています。
エラーに適切に対処するには例外を参照してください。
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");
先頭のアットマークはエスケープシーケンスの抑制記号です。
(エスケープシーケンス参照)
改行について
上記のサンプルコードでは改行文字に\n
を使用していますが、Windows環境でこれを実行すると出力されるファイルの改行文字はそのまま\n
になります。
Windowsでの改行文字は\r\n
なので、使用するテキストエディタによっては正常に改行されない場合があります。
環境に依らずに適切に改行文字を指定するにはEnvironment.NewLine
プロパティを使用します。
(System
名前空間)
string text1 = "This is Test." + Environment.NewLine + "あいうえお";
string text2 = $"This is Test.{Environment.NewLine}あいうえお";
なお、コンソール画面に対する出力では\n
でも正常に改行されます。
文字コードの指定
上記コードのテキストファイルはシステム規定の文字コードで書き込みされます。
文字コードを指定して書き込みする場合は第三引数に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
メソッドで指定します。
(staticメソッド)
このメソッドの引数には文字列か数値で文字コードを指定します。
具体的に指定できる値はマイクロソフトのヘルプを参照してください。
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型配列になる以外はFile.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
メソッドを使用します。
文字コードを指定して読み込み
文字コードを指定してテキストファイルを読み込むにはFile.ReadAllText
メソッドの第二引数にEncodingクラスを指定します。
これはテキストファイルの書き込みの時と同じです。
//「Shift_JIS」のテキストファイルの読み込み
string read = File.ReadAllText("test.txt", Encoding.GetEncoding("Shift_JIS"));
書き込み時の文字コードと読み込み時の文字コードが合っていないと文字化けを起こします。
他のプログラムで作成されたテキストファイルを読み込む場合などに起こることがあるので、文字コードの確認が必要です。
string型配列で取得
File.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型配列になる以外はFile.ReadAllText
メソッドと同じです。
文字コードの指定も同様です。
File.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. あいうえお Appended Text.
File.WriteAllText
メソッドがファイルの上書きなのに対して、File.AppendAllText
メソッドはファイルに追加するという動作に変わっただけです。
文字コードの指定なども同様に可能です。
指定のファイルが存在しない場合は新規に作成されます。
string配列、Listの追加
string型配列を一度に追加するにはFile.AppendAllLines
メソッドを使用します。
これもFile.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