C#でCSVファイルを読み込んでコレクションに入れてみた

データベースを使うまでもない小さなデータを、CSVファイル(カンマでデータを区切ったファイル)で扱うことありますよね。そのCSV形式のデータをC#アプリで読み取って、コレクションに入れてみます。 試した環境は下記です。

  • Visual Studio Express 2015 for Windows Desktop (C#)

目次

  1. C#でCSVファイルからデータを取り出すには
    1. TextFieldParserクラスとは
    2. コレクションとは
  2. 試してみた
    1. Visual Basic用のクラスをC#で使えるようにする
    2. コード
    3. 実行してみた
  3. まとめ

C#でCSVファイルからデータを取り出すには

CSVファイルからデータを取り出す方法として、読み込んだ文字列をカンマで分割したり、正規表現でフィールドを取り出したりする方法があります。それ以外に便利な方法として、Visual BasicのTextFieldParserを使う方法があります。こことか、MSDNのHow to: Read From Comma-Delimited Text Files in Visual Basicが参考になります。

TextFieldParserクラスとは

MSDNのTextFieldParserクラスに詳細が書かれていますが、抜粋してメモしておきます。 TextFieldParserクラスの第1引数はファイルのパスまたはストリーム、第2引数は文字エンコーディングです。

設定

解説

TextFieldTypeプロパティ

区切り形式(FieldType.Delimited)か固定幅形式(FieldType.FixedWidth)かをFieldType列挙体を指定します。

SetDelimiters()メソッド

区切り記号を設定します。

HasFieldsEnclosedInQuotesプロパティ

フィールドが引用符で囲まれているかどうかを指定します。trueは引用符付き、falseはそれ以外です。

TrimWhiteSpaceプロパティ

前後の空白を取り除くかどうか指定します。空白を取り除く場合はtrue、それ以外はfalseです。

CommentTokensプロパティ

コメント行の行頭文字を指定します。

ReadFields()メソッド

一行読み込んで文字列の配列を返します。

TextFieldParserクラスをC#で使うためには、参照にVisual Basicを追加してusing句でMicrosoft.VisualBasic.FileIOを宣言しておかなければなりません。

コレクションとは

コレクションは、オブジェクトを集めたものです。配列は使う前に大きさを決めなければならないのですが、コレクションは後からデータ(オブジェクト)を追加できますので、データの数が変動したり不明なものを扱う場合に便利です。詳しくは解説書を参照してください。 今回は、Dictionary型のコレクションを使ってみます。辞書のように、キーの文字列と値(バリュー)の文字列を、1対1で扱うものです。

試してみた

コンソールアプリで、test.txtというCSV形式のファイルを読み込んで、コレクションに格納された全てのデータをコンソールに出力するアプリを作ってみます。

Visual Basic用のクラスをC#で使えるようにする

まず、Visual Basicを参照に追加します。参照を右クリックして、右クリックメニューから「参照の追加」を選びます。 151219-1-01 「参照マネージャー」ウィンドウが開くので、「アセンブリ」→「フレームワーク」を選択して、表示されたリストの中から「Microsoft.VisualBasic」にチェックを付けて、「OK」します。 151219-1-02 そうすると、ソリューションエクスプローラーウィンドウの「参照」の中にMicrosoft.VisualBasicが追加されます。 151219-1-03

コード

Visual Basicを参照に追加すると、Microsoft.VisualBasic.FileIO名前空間が使えるようになります。using句に下記を追加します。

using Microsoft.VisualBasic.FileIO;

全体のコードは下記のようにします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic.FileIO;

namespace csv_trial
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> CsvData = new Dictionary<string, string>(); // 辞書型のコレクションを設定する

            TextFieldParser parser = new TextFieldParser("test.txt",System.Text.Encoding.GetEncoding("Shift_JIS")); // CSVパーサーにファイルと文字コードを設定する

            using (parser)
            {
                parser.TextFieldType = FieldType.Delimited; // 区切り形式とする
                parser.SetDelimiters(","); // 区切り文字はコンマとする
                parser.CommentTokens = new string[] { "#" }; // #で始まる行はコメントとする
                parser.HasFieldsEnclosedInQuotes = true; // 引用符付きとする
                parser.TrimWhiteSpace = true; // 空白文字を取り除く

                while (!parser.EndOfData)
                {
                    string[] row = parser.ReadFields(); // 1行読み込んでフィールド毎に配列に入れる

                    row[0] = row[0].Replace(" ", "_"); // 空白を_に変換する
                    row[1] = row[1].Replace(" ", "_"); // 空白を_に変換する
                    CsvData.Add(row[0], row[1]); // コレクションに追加する
                }
            }

            foreach (KeyValuePair<string, string> pair in CsvData)
            {
                Console.WriteLine(pair.Key + " : " + pair.Value);
            }
        }
    }
}

「1行あたり2つのデータを持つCSVファイルを読み取る」という前提のプログラムです。 読み取るデータとして、下図のデータを準備しました。 151219-1-04 TextFieldParserの設定を変えて、どうなるか試してみたいと思います。

実行してみた

TextFieldParserの設定を変えて、試してみました。まず、共通の設定です。

設定

TextFieldType

FieldType.Delimited (区切り形式)

SetDelimiters

"," (カンマ区切り)

CommentTokens

"#" (#で始まる行はコメント)

おそらく、下記の設定をする場合が多いと思います。

設定

HasFieldsEnclosedInQuotes

true (引用符付き)

TrimWhiteSpace

true (前後の空白を除去)

結果は下図のようになります。こうすると、データとして扱いやすいですよね。引用符が付いていないデータが混ざっていても、エラーにはなりません。引用符の中の空白も除去されます。 151219-1-05 次に、引用符無しという指定をしてみます。

設定

HasFieldsEnclosedInQuotes

false (引用符無し)

TrimWhiteSpace

true (前後の空白を除去)

結果は下図のようになります。データに引用符(ダブルクォーテーション)が含まれます。引用符の外側だけ、空白が除去されます。 151219-1-06 次に、空白の除去を止めてみます。

設定

HasFieldsEnclosedInQuotes

true (引用符有り)

TrimWhiteSpace

false (前後の空白を除去しない)

結果は下図のようになります。引用符が付いているデータについては引用符の内側だけが評価されて、引用符の外側の空白は無視されたようです。 151219-1-07

まとめ

Visual BasicのTextFieldParserクラスを使うことで、C#でも楽にCSVファイルを読み込めます。自分で文字列からいちいち切り出さなくても良いので、楽ですね。

公開日

広告