C#(Dotnet)でCSVファイルを扱う
C#(Dotnet)でCSVファイルを扱う
以前、C#でCSVファイルを読み込むにて、C#(dotnet)でCSVファイルを読み込む方法を紹介していました。
前回からの改良点や、追加した部分を紹介していこうと思います!
なおGitには最新のコードやdllを配置しているので、よかったら見てみてください。
「こうするべきでは?」というのがあれば連絡もらえると嬉しいです!
・https://github.com/flying-YT/CSV4net/tree/master
読み込みクラスの改良点
以前のコードでは値をそのまま配列に格納していましたが、ダブルクォーテーションで囲われている場合はダブルクォーテーションを含めて配列格納していました。
しかし、実際には値はダブルクォーテーションを含まず取り出したいケースがあると思い、囲っているダブルクォーテーションを削除するように仕様変更しています。
具体的な変更点としては、下記配列を格納する部分で正規表現を使っています。
- 変更前
var strArray = new string[separateList.Count]; foreach (var item in separateList.Select((value, index) => new { value, index })) { strArray[item.index] = item.value; }
var strArray = new string[separateList.Count]; foreach (var item in separateList.Select((value, index) => new { value, index })) { Match m = Regex.Match(item.value, "\"(?(.|\\r\\n)*?)\""); if(m.Success) { strArray[item.index] = m.Groups["data"].Value; } else { strArray[item.index] = item.value; } }
今まではforeach分の中で、そのまま配列に格納していましたが、
正規表現を使い、ダブルクォーテーションで囲われた文字列を検知するようにしています。
グループ化もしているので、マッチする場合にはダブルクォーテーションの中身のみを取り出し、配列格納するように修正しています。
マッチしない場合はダブルクォーテーションで囲われていないデータになるので、以前同様にそのまま配列格納しています。
ダブルクォーテーションで囲う場合は、改行を含んでいるケースが多いので、任意の文字列または改行を検知できるようにしています。
なお、上記改行コードは「\n」のみのケースもあるのでは?と思うかもしれませんが、データ読み込み中に下記コードを追加しているので、改行コードは「\r\n」確定になります。
先ほどのダブルクォーテーション処理も反映させたコードは下記です。
- 変更前
if(!isDoubleQuotation) { separateList.Add(sb.ToString()); sb = new StringBuilder(); var strArray = new string[separateList.Count]; foreach (var item in separateList.Select((value, index) => new { value, index })) { strArray[item.index] = item.value; } separateList = new List(); returnList.Add(strArray); }
if(isDoubleQuotation) { sb.Append("\r\n"); } else { separateList.Add(sb.ToString()); sb = new StringBuilder(); var strArray = new string[separateList.Count]; foreach (var item in separateList.Select((value, index) => new { value, index })) { Match m = Regex.Match(item.value, "\"(?(.|\\r\\n)*?)\""); if(m.Success) { strArray[item.index] = m.Groups["data"].Value; } else { strArray[item.index] = item.value; } } separateList = new List(); returnList.Add(strArray); }
CSVファイルの書き込みクラス
今までは、CSVファイルの読み込みのクラスを作成していましたが、CSVファイルで出力したいケースも存在するかと思います。
そのため、新たに書き込み用クラスのWritingFileを作成しました。
ファイル出力の際に、ダブルクォーテーションをつけて出力するか、つけないかの選択ができるようにしています。
ただし、改行コードを含む場合は強制的にダブルクォーテーションをつけてその値を書き込みます。
引数にはstring型の配列を値とするListと、出力先のフォルダパスになります。
また、値をダブルクォーテーションで囲うかを判定するためのbool値も引数に含んでいます。デフォルトは囲わない形式です。
その他には、区切り文字や文字コードの指定をすることが可能です。
public static void WriteCSV(Listlist, string path, bool isDoubleQuotation=false, char separate=',', string encoding="utf-8") { List writeList = new List (); foreach (string[] strArray in list) { StringBuilder sb = new StringBuilder(); foreach(string str in strArray) { if(isDoubleQuotation) { sb.Append("\"" + str + "\"" + separate); } else { if(str.Contains("\r\n") || str.Contains("\n")) { sb.Append("\"" + str + "\"" + separate); } else { sb.Append(str + separate); } } } string text = sb.ToString(); writeList.Add(text.Remove(text.Length - 1)); } WriteFile(writeList, path, encoding); }
WriteFileメソッドは下記になります。
public static void WriteFile(Listlist, string path, string encoding="utf-8") { using(StreamWriter sr = new StreamWriter(path, false, Encoding.GetEncoding(encoding))) { foreach(string str in list) { sr.WriteLine(str); } } }
以上がCSVファイルの出力クラスです。
さいごに
このような形でdotnet用のCSV操作ライブラリを作成しています。
自分自身、仕事中のログ分析で結構活用しています。
もしよければ、使ってみての感想や、不具合などあれば連絡いただけると嬉しいです。
自分自身でも使いながらデバック・改善をしていきますので、引き継ぎよろしくお願いいたします。
コメント
コメントを投稿