using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using Microsoft.VisualBasic.FileIO;
namespace DataAnalysis {
class CsvFile {
public string[] Headers { get; private set; }
public List<string[]> Data { get; private set; }
public int Cols { get { return Headers.Length; } }
public int Rows { get { return Data.Count; } }
public bool IsOpen { get { return Headers != null; } }
public string ErrorMsg { get; private set; }
Dictionary<string, int> _HeaderIndex;
/// <summary>
/// ファイルを開く
/// </summary>
/// <param name="filename">ファイル名</param>
/// <param name="requiredFields">必須列名</param>
public void Open(string filename, IEnumerable<string> requiredFields) {
var contents = ReadContents(filename);
Headers = contents.First();
if (!requiredFields.All(s => Headers.Contains(s))) {
Headers = null;
Data = null;
throw new Exception("CSVファイルに必要な列がありません");
}
Data = contents.Skip(1).ToList();
// インデックス辞書作成
_HeaderIndex = Headers.Select((s, idx) => new { str = s, idx = idx })
.ToDictionary(s => s.str, s => s.idx);
}
/// <summary>
/// ヘッダの列番号(インデックス)を返す
/// </summary>
/// <param name="header">列番号(0開始)</param>
/// <returns></returns>
public int HeaderIndex(string header) {
return _HeaderIndex[header];
}
/// <summary>
/// CSVファイルを読み込む
/// </summary>
/// <param name="path"></param>CSVファイル名
/// <param name="separator"></param>デリミタ
/// <param name="encoding"></param>エンコード
/// <returns></returns>
public static IEnumerable<string[]> ReadContents(
string path, string separator = ",", Encoding encoding = null) {
using (Stream stream =
new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
using (TextFieldParser parser =
new TextFieldParser(stream, encoding ?? Encoding.GetEncoding("Shift_JIS"), true, false)) {
parser.TextFieldType = FieldType.Delimited;
parser.Delimiters = new[] { separator };
parser.HasFieldsEnclosedInQuotes = true;
parser.TrimWhiteSpace = true;
while (parser.EndOfData == false) {
string[] fields = parser.ReadFields();
yield return fields;
}
}
}
}
}