CSVファイルを読み込むには?[2.0のみ、C#、VB].NET TIPS

CSVファイル(コンマ区切りのファイル)を読み込む処理には、.NET Framework 2.0で追加されたTextFieldParserクラスを活用すると便利だ。C#およびVB.NETでの使い方を解説する。

» 2006年08月18日 05時00分 公開
[遠藤孝信デジタルアドバンテージ]
「.NET TIPS」のインデックス

連載目次

 CSVファイル(コンマ区切りのファイル)を読み込む処理は、フィールド自体にコンマが含まれていたり、フィールドがダブルクオーテーションで囲まれていたりする場合などがあり、結構面倒な作業である*

* CSVファイルの仕様については以前は明確なものがなかったが、現在ではRFC4180により標準化されている。


 しかし.NET Framework 2.0には、主にVB 2005用の機能として、CSVファイルを読み込み、解析を行ってくれる非常に便利なTextFieldParserクラス(Microsoft.VisualBasic.FileIO名前空間)が追加されている。このクラスを使えば、CSVを読み込んで各行の各フィールドの文字列を簡単に取り出すことができる。

 もちろんこのTextFieldParserクラスはC#からも利用可能だ。本稿ではこのクラスを使ってCSVファイルを読み込むための方法について解説する。

TextFieldParserクラスによるCSVファイルの読み込み

 TextFieldParserクラスを使用してCSVファイルを読み込むには、まず処理したいCSVファイルをコンストラクタで指定してインスタンスを作成する。

 CSVファイルに日本語が含まれている場合には、ここでエンコーディングも指定可能だ(以降のコード例は上がC#、下がVBの場合)。

TextFieldParser parser = new TextFieldParser("text.csv",
    System.Text.Encoding.GetEncoding("Shift_JIS"));

Dim parser As New TextFieldParser("text.csv", _
    System.Text.Encoding.GetEncoding("Shift_JIS"))

TextFieldParserクラスのコンストラクタ呼び出し

 次にTextFieldTypeプロパティにFieldType.Delimitedを設定する(FieldType.FixedWidthを指定すればフィールドが固定幅のファイルも扱うことができる)。

 また、SetDelimitersメソッドを呼び出して区切り文字を設定しておく(複数の区切り文字が指定可能)。CSVファイルの場合にはもちろんコンマを指定する。

parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(","); // 区切り文字はコンマ

parser.TextFieldType = FieldType.Delimited
parser.SetDelimiters(",") ' 区切り文字はコンマ

フィールドがコンマで区切られている場合の設定

 あとはReadFieldsメソッドを呼び出すごとに、CSVファイルを1行ずつ読むことができる。このメソッドは、読み込んだ行の全フィールドを文字列の配列として返す。

 読み込むべき行がまだ残っているかどうかはEndOfDataプロパティにより判定できるので、次のようなループによりCSVファイル全体を処理できる。

while (!parser.EndOfData) {
  string[] row = parser.ReadFields(); // 1行読み込み

  // 配列rowの要素は読み込んだ行の各フィールドの値

}

While Not parser.EndOfData
  Dim row As String() = parser.ReadFields() ' 1行読み込み

  ' 配列rowの要素は読み込んだ行の各フィールドの値

End While

CSVファイル全体を読み込みながら処理するループ

CSVファイルを読み込み、表示するサンプル・プログラム

 次に示すサンプル・プログラムは、CSVファイルであるtext.csvを読み込み、各フィールドを切り出してTAB区切りで画面に出力する。

 なおこのプログラムでは、改行文字や空白文字がどのように処理されるかを分かりやすくするために、それぞれを「n」と「_」に置き換えて出力する。

// csvparser.cs

using System;
using Microsoft.VisualBasic.FileIO;

class CSVParser {
  static void Main() {

    TextFieldParser parser = new TextFieldParser("text.csv",
      System.Text.Encoding.GetEncoding("Shift_JIS"));

    using (parser) {
      parser.TextFieldType = FieldType.Delimited;
      parser.SetDelimiters(","); // 区切り文字はコンマ

      // parser.HasFieldsEnclosedInQuotes = false;
      // parser.TrimWhiteSpace = false;

      while (!parser.EndOfData) {
        string[] row = parser.ReadFields(); // 1行読み込み

        foreach (string field in row) {
          string f = field;
          f = f.Replace("\r\n", "n"); // 改行をnで表示
          f = f.Replace(" ", "_"); // 空白を_で表示
          Console.Write(f + "\t"); // TAB区切りで出力
        }
        Console.WriteLine();
      }
    }
  }
}

// コンパイル方法:csc /r:microsoft.visualbasic.dll csvparser.cs

CSVファイルを読み込み、表示するC#のサンプル・プログラム(csvparser.cs)
csvparser.csのダウンロード

' csvparser.vb

Imports System
Imports Microsoft.VisualBasic.FileIO

Class CSVParser
  Shared Sub Main()

    Using parser As New TextFieldParser("text.csv", _
      System.Text.Encoding.GetEncoding("Shift_JIS"))

      parser.TextFieldType = FieldType.Delimited
      parser.SetDelimiters(",") ' 区切り文字はコンマ

      ' parser.HasFieldsEnclosedInQuotes = False
      ' parser.TrimWhiteSpace = False

      While Not parser.EndOfData
        Dim row As String() = parser.ReadFields() ' 1行読み込み

        For Each field As String In row
          field = field.Replace(vbCrLf, "n") ' 改行をnで表示
          field = field.Replace(" ", "_") ' 空白を_で表示
          Console.Write(field + vbTab) ' TAB区切りで出力
        Next
        Console.WriteLine()
      End While
    End Using
  End Sub
End Class

' コンパイル方法:vbc csvparser.vb

CSVファイルを読み込み、表示するVBのサンプル・プログラム(csvparser.vb
csvparser.vbのダウンロード

 このサンプル・プログラムに次のような内容のCSVファイルを読み込ませた場合の出力を以下に示す。

あああ   , いいい     , ううう
"あああ" , "いいい"   , " ううう "
"あああ" , "い""いい" , "ううう"
"あああ" , "い,いい"  , "ううう"
あああ
あああ   , いいい
"あああ" , "い
いい","ううう"


サンプル・プログラムに読み込ませるCSVファイル(test.csv)の内容
最後の行は2番目のフィールドの途中に改行が入っている。

 このCSVファイルを読み込ませた場合のプログラムの出力は次のようになる(実際には出力はTAB区切りとなるが、ここでは分かりやすいように表形式に整形している)。

1カラム目 2カラム目 3カラム目
あああ いいい ううう
あああ いいい ううう
あああ い"いい ううう
あああ い,いい ううう
あああ    
あああ いいい  
あああ いnいい ううう
サンプル・プログラムの出力結果

 ダブルクオーテーションで囲まれているフィールドや、改行文字が含まれているフィールドも正しく処理されているのが分かる。またデフォルトの設定では、フィールドの前後にある空白文字が自動的に削除されているのも分かる。

■HasFieldsEnclosedInQuotesプロパティ

 すべてのフィールドが単純にコンマで区切られているものとして処理したい場合には、HasFieldsEnclosedInQuotesプロパティをfalseに設定する(デフォルトはtrue)。

 以下の出力結果は、上記のサンプル・プログラムでこのプロパティをfalseに設定した場合のものである。

1カラム目 2カラム目 3カラム目 4カラム目
あああ いいい ううう  
"あああ" "いいい" "_ううう_"  
"あああ" "い""いい" "ううう"  
"あああ" "い いい" "ううう"
あああ      
あああ いいい    
"あああ" "い    
いい" "ううう"    
HasFieldsEnclosedInQuotes=falseの場合の出力結果

 この場合にはダブルクオーテーションは処理されないのでそのまま出力される。フィールドの途中に改行が入っているデータは2つの行として扱われることになる。

■TrimWhiteSpaceプロパティ

 フィールド前後の空白文字を削除したくない場合にはTrimWhiteSpaceプロパティをfalseに設定する(デフォルトはtrue)。

 上記のサンプル・プログラムでこのプロパティをfalseに設定した場合の出力結果を以下に示す(HasFieldsEnclosedInQuotesプロパティはtrueのまま)。

1カラム目 2カラム目 3カラム目
あああ___ _いいい_____ _ううう
あああ いいい _ううう_
あああ い"いい ううう
あああ い,いい ううう
あああ    
あああ___ _いいい  
あああ いnいい ううう
TrimWhiteSpace=falseの場合の出力結果

 ダブルクオーテーションで囲まれていないフィールドは、区切り文字であるコンマ以外の文字がすべて出力されている。また、ダブルクオーテーションで囲まれているフィールドは、ダブルクオーテーション内のフィールドの前後の空白文字が削除されない。

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:テキスト・ファイル
使用ライブラリ:TextFieldParserクラス(Microsoft.VisualBasic.FileIO名前空間)
使用ライブラリ:FieldType列挙体(Microsoft.VisualBasic.FileIO名前空間)


「.NET TIPS」のインデックス

.NET TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。