【C#】 CSVのヘッダーだけ読み込んで出力する
うぃろぅです。
C#の新しい案件を進めているのはいいものの、どことなーくレガシーな気配が漂っている現状です。
まぁ嘆いていても始まらないので業務をこなすわけですが、その際に「あーこれしないとな、でも手作業だと面倒だからツール作ろう」と作った備忘録。
何がしたいか
date,time,foo,bar,baz 2019/2/25,00:00,1,2,3 2019/2/25,00:05,4,5,6 2019/2/25,00:10,7,8,9 . . .
上記のようなCSVファイルがあるとして、これを
date time foo bar baz
こうしたい。なんて簡単な。
何でこんなことをしたくなったかというと現新比較がしたかったから。
- 現行フォーマットで出力されているCSVがある
(dateTime,hoge,hugaみたいな感じで結構違う) - 新フォーマットで出力されるように変更する
- 現行フォーマットのCSVをVBAで取り込んで処理を行っているため、新フォーマットだと動かない
- VBAは10年くらい前に当時の作業者が片手間で作ったため読み解くのにコストがかかる
- よって新フォーマットのCSVを現行フォーマットに変換したい
みたいな流れ。その際に変換リストの上から順番に出力されるようにしたら順番が違っている。
なのでWinMergeのようなDiffソフトで比較して修正するのが手っ取り早いよね、というワケ。
そもそもツールが動かない場合に頑張って解析しなきゃいけないとか、もう使わないファイルもあるけれどファイル名がないとエラーが出るからダミーファイルに置き換えるとか、もうそれ新フォーマット取り込む新しいツール作成した方がいいのでは、なんて突っ込みは野暮というもの。予算が悪いよ予算が。
ここ1ヶ月くらいでやったことは、
ってところ。DBは使わないらしい。うーんレガシー。まあ管理コストかからないからこれはこれでありか。…いや、ありか??
ちなみにこのCSVファイル、150種類くらいある。XMLファイル作るのめっちゃ大変だった。
閑話休題。以下ソース。
using System.Text; using System.IO; using Microsoft.VisualBasic.FileIO; static void Main(string[] args) { // Shift-JISで出力されるので合わせる var sJis = Encoding.GetEncoding("Shift-JIS"); var path = @"C:\Users\sample\csv"; var csvs = Directory.GetFiles(path); // 読み込んだファイル数分ループ foreach (var csv in csvs) { // CSV読み込み var parser = new TextFieldParser(csv, sJis)) { TextFieldType = FieldType.Delimited, Delimiters = new string[] { "," } }; // ヘッダー読み込み var heads = parser.ReadFields(); // 出力先設定 var outPath = Path.Combine( path, "header", Path.GetFileName(csv)); // 出力 using (var sw = new StreamWriter(outPath, false, sJis)) { foreach(var head in heads) { sw.WriteLine(head); } } } }
かんたーん!
CSV読み込みにはTextFieldParser
を利用。
Microsoft.VisualBasic
を参照に追加する必要があるためそこだけ注意。
CSVの格納フォルダを決め打ちしているが、configファイルから読み込むようにすればリビルド不要。
System.Configuration.ConfigurationManager.AppSettings["inputCsvPath"];
みたいな感じか。
最適化とか全然していないけれど、これで動きそうだしいいかと。
サブ作業に時間かけてもしょうがないし。将来の自分へのメモ。
役に立つかは知らない。多分立たないかなぁ。
ではまた。