.NET Framework 4以降では、FileクラスのReadLinesメソッドを使うことで、テキストファイルに対する反復処理を簡単かつ効率的に行える。
本稿は2010/05/13に初版公開された記事を改訂し、Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行ったものです。
「TIPS:テキストファイルの内容を簡単に読み込むには?」では、Fileクラス(System.IO名前空間)のReadAllLinesメソッドにより、テキストファイルの内容を配列に読み込む方法を紹介しているが、このメソッドは全行を一度に読み込むため、巨大なテキストファイルでは呼び出し時に時間がかかる。
このため、先頭から1行ずつ処理したいような場合には、「TIPS:テキストファイルの内容を読み込むには?」の後半で紹介しているように、StreamReaderクラス(System.IO名前空間)などを使用する必要があった。
本稿で紹介するFileクラスのReadLinesメソッドを使えば、そのような先頭から1行ずつ処理するコードを簡単に書ける。
特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
テキストファイルの読み込みには、その目的や利用している.NET Frameworkのバージョンによって、さまざまな方法がある。適切な方法を選んでほしい。特に.NET Framework 4.5以降でクライアントアプリを作る場合は、非同期的に読み込む方法が適している。
.NET Framework 4では、Fileクラスに新しくReadLinesメソッドが追加されている。
このメソッドも、引数に指定したテキストファイルを1行ずつ読み込むためのものだが、メソッドの呼び出し時にはファイルを読み込まない。代わりに列挙子オブジェクトを返し、その列挙時(反復処理時)に1行ずつ読み込むため、行単位の作業を効率よく記述できる。
以下にReadLinesメソッドの記述例を示す。これは、テキストファイルを1行ずつ読み込み、それを画面に表示する。
// readlines.cs
using System;
using System.IO;
using System.Collections.Generic;
class Program {
static void Main() {
string fileName = @"c:\tmp\readme.txt";
IEnumerable<string> lines = File.ReadLines(fileName);
foreach (string line in lines) {
Console.WriteLine(line);
}
}
}
// コンパイル方法:csc readlines.cs
' readlines.vb
Imports System.IO
Class Program
Shared Sub Main()
Dim fileName As String = "c:\tmp\readme.txt"
Dim lines As IEnumerable(Of String) = File.ReadLines(fileName)
For Each line In lines
Console.WriteLine(line)
Next
End Sub
End Class
' コンパイル方法:vbc readlines.vb
このように、ReadLinesメソッドの戻り値はIEnumerable<string>クラス(VBではIEnumerable(Of String)と記述)*1のオブジェクトとなる。このため、実際に各行を読み込むためには、foreach文(VBではFor Each文)を使用することになる(あるいはLINQのデータソースとして利用できる)。
なお、ReadLinesメソッドはファイル末尾の改行記号を無視する(あってもなくても同じ結果になる)。たいていのテキストエディタは、ファイル末尾に改行記号があるときはその後ろにもう1行あるように表示する。それと比べると、ファイル末尾に改行記号がある場合にReadLinesメソッドで得られる行数は1行少なくなる。
*1 System.Collections.Generic名前空間のジェネリッククラスである、IEnumerable<T>クラス(VBではIEnumerable(Of T)と記述)をString型に適用したクラス。
UTF-8以外の文字コードのファイルを使用する場合には、ReadLinesメソッドの第2引数で、ファイルの文字コードに該当するEncodingオブジェクト(System.Text名前空間)を指定する。
次のサンプルプログラムではシフトJISのファイルを処理している。
// readlines2.cs
using System;
using System.IO;
using System.Text;
class Program {
static void Main() {
string fileName = @"c:\tmp\readme.txt"; // シフトJISファイル
Encoding SJIS = Encoding.GetEncoding("Shift_JIS");
foreach (string line in File.ReadLines(fileName, SJIS)) {
Console.WriteLine(line);
}
}
}
// コンパイル方法:csc readlines2.cs
' readlines2.vb
Imports System.IO
Imports System.Text
Class Program
Shared Sub Main()
Dim fileName As String = "c:\tmp\readme.txt" ' シフトJISファイル
Dim SJIS As Encoding = Encoding.GetEncoding("Shift_JIS")
For Each line In File.ReadLines(fileName, SJIS)
Console.WriteLine(line)
Next
End Sub
End Class
' コンパイル方法:vbc readlines2.vb
こちらのサンプルプログラムでは、ReadLinesメソッド呼び出しをforeach文(For Each文)に埋め込んでいる。このため列挙子オブジェクトを明示的には宣言していない。
利用可能バージョン:.NET Framework 4以降
カテゴリ:クラスライブラリ 処理対象:テキストファイル
使用ライブラリ:Fileクラス(System.IO名前空間)
使用ライブラリ:StreamReaderクラス(System.IO名前空間)
使用ライブラリ:IEnumerable<T>クラス(System.Collections.Generic名前空間)
使用ライブラリ:Encodingクラス(System.Text名前空間)
関連TIPS:テキストファイルの内容を簡単に読み込むには?[C#/VB、.NET 2.0以降]
関連TIPS:テキストファイルの内容を読み込むには?[C#/VB、.NET全バージョン]
関連TIPS:テキストファイルの内容を非同期的に読み込むには?[C#/VB、.NET 4.5]
関連TIPS:ファイルにテキストを書き込むには?[C#、VB]
関連TIPS:バイナリ・ファイルを読み書きするには?
関連TIPS:テキストファイルの内容を非同期的に書き込むには?[C#/VB、.NET 4.5]
関連TIPS:バイナリファイルを非同期的に読み書きするには?[C#/VB、.NET 4.5]
関連TIPS:CSVファイルを読み込むには?[2.0のみ、C#、VB]
【2019/01/09】Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行いました。
【2010/05/13】初版公開。
Copyright© Digital Advantage Corp. All Rights Reserved.