TextFieldParserは、あらかじめ決められた形式・フォーマットのテキストファイル、例えばCSVファイルなどを解析して読み取るためのクラス。

デリミタ(区切り文字)、コメント文字列等は自由に設定できるので、フォーマットさえ決まっていればこのクラスで読み取り可能。 CSVのようにデリミタでフィールド(データ)を区切るのではなく、データの幅が固定長になっているようなテキストファイルも読み取れる。

主なコンストラクタ

TextFieldParser(string)
読み込むファイルのパスを指定してインスタンスを生成する。
TextFieldParser(Stream, Encoding)
読み込むデータストリームと、エンコーディングを指定してインスタンスを生成する。

主なプロパティ

TextFieldType (FieldType)
読み込む対象のフォーマットを指定する。 デリミタで区切られるデータで構成されるフォーマット(FieldType.Delimited)か、固定長の幅のデータで構成されるフォーマット(FieldType.FixedWidth)かどちらかを指定する。
CommentTokens (string[])
コメントとして扱う行頭文字をstring[]で指定する。 例えば#で始まる行と'で始まる行をコメント行としたい場合は、{"#", "'"}を指定する。
Delimiters (string[])
デリミタとして扱う文字をstring[]で指定する。 例えばCSV形式のように,を区切り文字としたい場合は、{","}を指定する。
FieldWidths (int[])
TextFieldTypeがFieldType.FixedWidthの場合、それぞれのフィールドの幅をint[]で指定する。 例えば任意の1行のフォーマット「名前が10文字、住所が30文字、電話番号が11桁」であれば、{10, 30, 11}のように指定する。
HasFieldsEnclosedInQuotes (bool)
フィールドに改行やデリミタを含める為に引用符を使っているようなフォーマットを考慮する場合は、Trueを指定する。
TrimWhiteSpace (bool)
フィールドを読み取った結果、前後に空白が含まれる場合に、その空白を削除するかどうか指定する。
EndOfData (bool)
このプロパティがTrueのとき、これ以上読み取れるデータがないことを表す。

主なメソッド

string[] ReadFields()
一行読み取り、指定されたフォーマットに従って解析した結果をstring[]で返す。 フォーマットに反する行を読み取ろうとした場合は、MalformedLineExceptionがスローされる。
string PeekChars(int)
ストリームの読み取り位置を変えずに、指定された文字数分読み取る。 このメソッドを呼ぶとき、ただ単に直前に解析した行の続きを読むのではなく、コメント行などを無視して次に解析できる行を読もうとする。 そのため、PeekChars()メソッドではコメント行や不正な形式の行は読み取ることはできない。

主な呼び出し順序

  1. new TextFieldParser()
  2. ReadFields()
  3. Close()

使用例

TextFieldParserを使ってCSVファイルを読み込み、表示する。

Sponsored Link

Imports System
Imports System.Text
Imports Microsoft.VisualBasic.FileIO

Class TextFieldParserSample

  Public Shared Function Main() As Integer

    Dim parser As TextFieldParser = Nothing

    Try

      parser = New TextFieldParser( "sample.csv", Encoding.UTF8 )

      ' フィールドはデリミタにより区切られている(固定長の形式ではない)
      parser.TextFieldType = FieldType.Delimited

      ' 「#」で始まる行をコメントとして扱う
      parser.CommentTokens = New String() {"#"}

      ' 「,」をデリミタとして扱う
      parser.Delimiters = New String() {","}

      ' 引用符でくくられたフィールドを持つ
      parser.HasFieldsEnclosedInQuotes = True

      ' フィールドの前後に含まれる空白をトリムする
      parser.TrimWhiteSpace = True

      ' データがなくなるまで読み取り続ける
      Do Until parser.EndOfData

        Try

          ' 一行分のフィールドを読む
          Dim fields As String() = parser.ReadFields()

          Console.Write( "Line {0:D3} :", parser.LineNumber - 1 )

          For Each field As String In fields

            ' 読み取った各フィールドを大括弧でくくって表示する
            Console.Write( "[{0}] ", field )

          Next

          Console.WriteLine()

        Catch ex As MalformedLineException

          ' 読み込んでいる途中で指定したフォーマットに反するような行が見つかった場合
          Console.WriteLine( ex.Message )

          If parser IsNot Nothing Then

            ' 読み込めなかった行に関する情報を表示する
            Console.WriteLine( "Error at line {0}: {1}", parser.LineNumber, parser.ErrorLine )

          End If

        End Try

      Loop

    Finally

      If parser IsNot Nothing Then parser.Close()

    End Try

    Return 0

  End Function

End Class

sample.csvは次のような内容のCSV形式のテキストファイルとする(エンコーディングはUTF-8とする)。

# comment line
123,abc,XYZ
,日本語(UTF8),
#,comment,line,with,delimiter
"column with 
newline","column with ""quotes""","column, with, commas","   column   with    spaces   "
invalid (format line;","
"invalid new line,
あ、i,う。
# end of data

実行結果は次のとおり。

Line 002 :[123] [abc] [XYZ]
Line 003 :[] [日本語(UTF8)] []
Line 006 :[column with
newline] [column with "quotes"] [column, with, commas] [column   with    spaces]

現在の区切り記号を使用して、行 7 を解析できません。
Error at line 9: invalid (format line;","
"invalid new line,
Line 009 :[あ、i] [う。]