C#でCSVファイルを読み込んでコレクションに入れてみた
データベースを使うまでもない小さなデータを、CSVファイル(カンマでデータを区切ったファイル)で扱うことありますよね。そのCSV形式のデータをC#アプリで読み取って、コレクションに入れてみます。 試した環境は下記です。
Visual Studio Express 2015 for Windows Desktop (C#)
目次
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を参照に追加します。参照を右クリックして、右クリックメニューから「参照の追加」を選びます。 「参照マネージャー」ウィンドウが開くので、「アセンブリ」→「フレームワーク」を選択して、表示されたリストの中から「Microsoft.VisualBasic」にチェックを付けて、「OK」します。 そうすると、ソリューションエクスプローラーウィンドウの「参照」の中にMicrosoft.VisualBasicが追加されます。
コード
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ファイルを読み取る」という前提のプログラムです。 読み取るデータとして、下図のデータを準備しました。 TextFieldParserの設定を変えて、どうなるか試してみたいと思います。
実行してみた
TextFieldParserの設定を変えて、試してみました。まず、共通の設定です。
設定 |
値 |
---|---|
TextFieldType |
FieldType.Delimited (区切り形式) |
SetDelimiters |
"," (カンマ区切り) |
CommentTokens |
"#" (#で始まる行はコメント) |
おそらく、下記の設定をする場合が多いと思います。
設定 |
値 |
---|---|
HasFieldsEnclosedInQuotes |
true (引用符付き) |
TrimWhiteSpace |
true (前後の空白を除去) |
結果は下図のようになります。こうすると、データとして扱いやすいですよね。引用符が付いていないデータが混ざっていても、エラーにはなりません。引用符の中の空白も除去されます。 次に、引用符無しという指定をしてみます。
設定 |
値 |
---|---|
HasFieldsEnclosedInQuotes |
false (引用符無し) |
TrimWhiteSpace |
true (前後の空白を除去) |
結果は下図のようになります。データに引用符(ダブルクォーテーション)が含まれます。引用符の外側だけ、空白が除去されます。 次に、空白の除去を止めてみます。
設定 |
値 |
---|---|
HasFieldsEnclosedInQuotes |
true (引用符有り) |
TrimWhiteSpace |
false (前後の空白を除去しない) |
結果は下図のようになります。引用符が付いているデータについては引用符の内側だけが評価されて、引用符の外側の空白は無視されたようです。
まとめ
Visual BasicのTextFieldParserクラスを使うことで、C#でも楽にCSVファイルを読み込めます。自分で文字列からいちいち切り出さなくても良いので、楽ですね。
公開日
広告
C#の入出力カテゴリの投稿
- C#でCSVファイルを読み込んでコレクションに入れてみた
- C#でInputBoxを使ってみた
- C#で「名前を付けて保存」ダイアログを使ってみた
- C#でクリップボードから文字列を取得する
- C#でクリップボードにデータを入れる
- C#でコマンドライン引数を取得する
- C#でテキストファイルを読んでみた (File.ReadAllText編)
- C#でドロップされたファイルの名前を得る(WPF編 DragOver版)
- C#でドロップされたファイルの名前を得る(WPF編 PreviewDragOver版)
- C#でドロップされたファイルの名前を得る(Windowフォーム編)
- C#でパイプを使ってデータを入力してみる
- C#でメッセージボックスを使う