HOWTO · Csharp

C# で CSV ファイルを読み込み、その値を配列に格納する

このハウツー記事では、CSV ファイルを読み取り、その値を C# の配列に格納するさまざまな方法を示します。OpenRead()、ReadLine()、TextFieldParser などのメソッドが導入されています

このページの内容

CSV ファイルはカンマ区切りのファイルで、整理された方法でデータを保存するために使用されます。通常、データは表形式で格納されます。ほとんどの企業では、データを CSV ファイルに保存しています。

C# では、CSV ファイルに対してさまざまな操作を実行できます。CSV ファイルの読み取り、書き込み、変更が可能です。この記事では、CSV ファイルを読み取ってその値を配列に格納する 2 つの方法、StreamReader で行を読み取る方法と、TextFieldParser でフィールドを解析する方法に焦点を当てます。

どちらの例も、同じサンプル Data.csv ファイルを使用します。

Name,Age
Alice,30
Bob,25

StreamReader で CSV ファイルを読み取る

StreamReader クラスは、ファイルをテキストのストリームとして読み取ります。File.OpenRead() でファイルを開き、ReadLine() は EndOfStream に達するまで一度に 1 行を返します。各行をカンマで分割すると個々の値が得られ、例では列ごとに 1 つのリストに格納します。

OpenRead() メソッドと ReadLine() メソッドを使用する正しい構文は次のとおりです。

// OpenRead() Syntax
File.OpenRead(@"FilePath");
// ReadLine() Syntax
StreamReaderObject.ReadLine();

サンプルコード:

using System.IO;
using System.Collections.Generic;
using System;

class ReadingCSV {
  static void Main(string[] args) {
    var reader = new StreamReader(File.OpenRead(@"D:\New folder\Data.csv"));
    List<string> listA = new List<string>();
    List<string> listB = new List<string>();
    while (!reader.EndOfStream) {
      var line = reader.ReadLine();
      var values = line.Split(',');

      listA.Add(values[0]);
      listB.Add(values[1]);
    }
    foreach (var column1 in listA) {
      Console.WriteLine(column1);
    }
    foreach (var column2 in listB) {
      Console.WriteLine(column2);
    }
  }
}

出力:

Name
Alice
Bob
Age
30
25

カンマでの分割は、フィールド自体にカンマが含まれていない場合に機能します。"Smith, John" のような引用符で囲まれたフィールドは間違った位置で分割されてしまいます。そのようなファイルには TextFieldParser を使用してください。

TextFieldParser で CSV フィールドを解析する

TextFieldParser クラスは、Microsoft.VisualBasic.FileIO 名前空間で定義されています。区切り文字のあるファイルをフィールドごとに解析し、引用符で囲まれたフィールドを理解します。SetDelimiters() で区切り文字を設定し、ReadFields() を呼び出すと現在の行のフィールドが文字列の配列として得られます。パーサーは呼び出すたびに次の行に移動します。.NET Framework プロジェクトでは、以下のプログラムを実行する前に Microsoft.VisualBasic への参照を追加してください。最新の .NET では、この名前空間は共有フレームワークの一部です。

このパーサーを使用する正しい構文は次のとおりです。

TextFieldParser ParserName = new TextFieldParser(PathString);

サンプルコード:

using System;
using System.Collections.Generic;
using Microsoft.VisualBasic.FileIO;

class ReadingCSV {
  public static void Main() {
    var path = @"D:\New folder\Data.csv";
    List<string> listA = new List<string>();
    List<string> listB = new List<string>();
    using (TextFieldParser csvReader = new TextFieldParser(path)) {
      csvReader.CommentTokens = new string[] { "#" };
      csvReader.SetDelimiters(new string[] { "," });
      csvReader.HasFieldsEnclosedInQuotes = true;

      // Skip the row with the column names
      csvReader.ReadLine();

      while (!csvReader.EndOfData) {
        // Read current line fields, pointer moves to the next line.
        string[] fields = csvReader.ReadFields();
        listA.Add(fields[0]);
        listB.Add(fields[1]);
      }
    }
    foreach (var column1 in listA) {
      Console.WriteLine(column1);
    }
    foreach (var column2 in listB) {
      Console.WriteLine(column2);
    }
  }
}

出力:

Alice
Bob
30
25

今回は、最初の ReadLine() でヘッダー行がスキップされ、手動の分割ではなくパーサーが各フィールドの終わりを判断するため、フィールド内の引用符で囲まれたカンマがそのまま保持されます。