今回はc#でcsvファイルを読み込む方法を紹介します。今回紹介する方法は、標準ライブラリだけを用いて実装できます。
コード全体
今回は読みこんだcsvのデータをリストに格納していくところまでを実装します。
using System.Collections.Generic;
using System.IO;
namespace readcsv
{
class Program
{
static void Main(string[] args)
{
string fileName = "apple_stock.csv";
//指定したcsvを開く
StreamReader sr = new StreamReader(@fileName);
List<string[]> lists = new List<string[]>();
int i = 0;
//1行ずつ処理
while (!sr.EndOfStream){
string line = sr.ReadLine();
if (i == 0){
//1行目はヘッダーとして別途取得
string[] cols = line.Split(',');
i += 1;
continue;
}
//カンマで配列の要素として分ける
string[] values = line.Split(',');
// 配列からリストに格納する
lists.Add(values);
}
}
}
}
ざっくり解説
StreamReaderを使う
csvの読込にはSystem.IO.StreamReaderを用います。StreamReaderの引数には読み込むファイルのパスを指定します。
引数fileNameの前についているアットマーク(@)は、文字列のエスケープ的な役割を果たします。@を付ければ、パスに\(バックスラッシュ)を含めてもエラーになりません。
string fileName = "apple_stock.csv";
//指定したcsvを開く
StreamReader sr = new StreamReader(@fileName);
1行ごとにデータ読込
while~から、1行ごとにデータを読み込んでリストに格納しています。StreamReader型の変数srにはcsv全体のデータが格納されており、それを1行ずつ読み取っていきます。
1行ずつ読むにはsr.ReadLine()を用います。変数lineには以下のような文字列でデータが入っています。csvの1行分、カンマ区切りのデータです。
"2015-11-23,2095.610107421875,2081.389892578125,2089.409912109375,2086.590087890625,3587980000.0,2086.590087890625"
カラムごとにデータを分けるには、カンマで文字列を分割して、配列とするのがよさそうです。カラムごとに分割したデータはvaluesに格納されます。ここで、if文内はcsvのヘッダー行(1行目)の処理です。ヘッダーは値ではないので、別出しで保持しています。
1行分のデータであるvaluesをリストであるlistsに全行分格納していきます。listsはcsvの行数分の要素数を持つリストとなります。
List<string[]> lists = new List<string[]>();
int i = 0;
//1行ずつ処理
while (!sr.EndOfStream){
string line = sr.ReadLine();
if (i == 0){
//1行目はヘッダーとして別途取得
string[] cols = line.Split(',');
i += 1;
continue;
}
//カンマで配列の要素として分ける
string[] values = line.Split(',');
// 配列からリストに格納する
lists.Add(values);
}
listsの中身を見てみます。要素数は1825で、これはcsvの行数と等しくなります(ヘッダーを除いた行数)。各行の要素は7つあり、これはカラム数と一致します。
StreamReaderでcsvを読み込むと、数値等も文字列として読み込んでしまいます。なので、実際に数値を使って計算するとなれば、データ型を変換する必要があります。
まとめ
c#でcsvファイルを読み込んでリストにデータを保持する方法を紹介しました。今回紹介した方法は最もシンプルで、外部パッケージをインストールする必要もありません。ただし全て文字列として読み込んでしまうので注意が必要です。
c#でcsvファイルを読み込む方法は他にもいくつかあります。それについては、後々紹介できればと思います。
ではでは👋