TextFieldParserでCSV(TSV)を読み込む方法
C#あるいはVB.NETでCSV(TSV)ファイルを扱うときに、TextFieldParserを使う方法を紹介します。CSVファイルを読み込んで処理するときに、単純に1行ずつ読み込んでカンマで分割してやる方法でも良いのですが、引用符(“”)つまりダブルクォーテーションで囲まれていたり、フィールド内に改行がある場合などの対応を考えると面倒だったりします。
TextFieldParserクラス(Microsoft.VisualBasic.FileIO名前空間)を使えば引用符(“”)やフィールド内の改行にも簡単に対応できます。.NET Framework 2.0以降であればC#でもVB.NET使えます。
TextFieldParserクラスの使い方
サンプルデータとして以下のCSVファイルを読み込んで処理するサンプルをC#,VB.NETそれぞれで用意しました。引用符(“”)に囲まれている列があり、フィールド内の改行もあります。
参照の追加
TextFieldParserクラスはMicrosoft.VisualBasic.FileIO名前空間にあるので、まずはMicrosoft.VisualBasicアセンブリへの参照を追加しておきます。
CSVテストデータ
C:\work\test.csv
番号,名前,性別,年齢
1,山田太郎,男,30
2,鈴木一郎,男,25
3,佐藤花子,女,20
4,"改行
テスト",男,20
C#
using System;
using System.Text;
using Microsoft.VisualBasic.FileIO;
namespace CsvParser
{
class Program
{
static void Main(string[] args)
{
var parser = new TextFieldParser(@"C:\work\test.csv",
Encoding.GetEncoding("Shift_JIS"));
using (parser)
{
// カンマ区切りの指定
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
// フィールドが引用符で囲まれているか
parser.HasFieldsEnclosedInQuotes = true;
// フィールドの空白トリム設定
parser.TrimWhiteSpace = false;
// ファイルの終端までループ
while (!parser.EndOfData)
{
// フィールドを読込
string[] row = parser.ReadFields();
foreach (string field in row)
{
// タブ区切りで出力
Console.Write(field + "\t");
}
Console.WriteLine();
}
}
Console.ReadKey();
}
}
}
VB.NET
Imports System.Text
Imports Microsoft.VisualBasic.FileIO
Module Module1
Sub Main()
Using parser As New TextFieldParser("C:\work\test.csv",
Encoding.GetEncoding("Shift_JIS"))
' カンマ区切りの指定
parser.TextFieldType = FieldType.Delimited
parser.SetDelimiters(",")
' フィールドが引用符で囲まれているか
parser.HasFieldsEnclosedInQuotes = True
' フィールドの空白トリム設定
parser.TrimWhiteSpace = False
' ファイルの終端までループ
While Not parser.EndOfData
' フィールドを読込
Dim row As String() = parser.ReadFields()
For Each field As String In row
' タブ区切りで出力
Console.Write(field + vbTab)
Next
Console.WriteLine()
End While
End Using
Console.ReadKey()
End Sub
End Module
出力結果
上のサンプルの実行結果は次のとおりになります。
番号 名前 性別 年齢
1 山田太郎 男 30
2 鈴木一郎 男 25
3 佐藤花子 女 20
4 改行
テスト 男 20
解説
TextFieldParserクラスのインスタンスを作成します。コンストラクタの引数でファイルのパスとエンコードを指定します。
TextFieldParserクラスのプロパティでファイルを読み込むための設定を行えます。今回の例だとCSVファイルを読み込みたいので、TextFieldTypeでFieldType.Delimitedを指定します。それからSetDelimitersで区切り文字を指定します。CSVだとカンマ、TSVならタブを指定します。
引用符(“”)に囲まれているかどうか、フィールドの空白をトリムするかどうかもそれぞれ、HasFieldsEnclosedInQuotes、TrimWhiteSpace で設定できます。
後はファイルの終端になるまでループするなりして処理します。ReadFieldsで1行分のデータを読み込んで、フィールドごとに分割して取得しています。
引用符(“”)ありとして設定していても、なしのフィールドもうまく処理できてるようです。
TextFieldParserクラスを使えばCSVファイル以外にも、固定長ファイルについても読み込むことができます。その方法もまたの機会に調べます。
参考URL
コメントを書く