#region Using using System; using System.Collections.Generic; using System.Text; #endregion namespace Wankuma.IO { /// /// CSVデータを読み取ります。 /// public class CSVReader : IDisposable { #region プロパティ #region protected System.IO.StreamReader Reader 実際のリーダである、ストリームリーダ /// /// 内部用リーダ /// private System.IO.TextReader reader_; /// /// 実際のリーダ /// private System.IO.TextReader Reader { get { return reader_; } set { reader_ = value; } } #endregion #region protected char 区切り文字 CSVの区切り文字 /// /// CSVの区切り文字 /// 初期値は',' /// private char 区切り文字_ = ','; /// /// CSVの区切り文字 /// 初期値は',' /// public char 区切り文字 { get { return this.区切り文字_; } private set { this.区切り文字_ = value; } } #endregion #region protected bool ファイル終了フラグ ファイルが終端まで行っているかのフラグ /// /// ファイルが終端まで行っているかのフラグ /// private bool ファイル終了フラグ_; /// /// ファイルが終端まで行っているかのフラグ /// public bool ファイル終了フラグ { get { return ファイル終了フラグ_; } private set { ファイル終了フラグ_ = value; } } #endregion #region protected bool 行終了フラグ 行が最後まで行っているかのフラグ /// /// 行が最後まで行っているかのフラグ /// private bool 行終了フラグ_; /// /// 行が最後まで行っているかのフラグ /// public bool 行終了フラグ { get { return 行終了フラグ_; } private set { 行終了フラグ_ = value; } } #endregion #endregion #region public CSVReader(System.IO.Stream stream) 指定したストリーム用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したストリーム用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれるストリーム。 /// stream が null です。 /// stream が読み取りをサポートしていません。 public CSVReader(System.IO.Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } this.Init(stream); } #endregion #region public CSVReader(System.IO.Stream stream, char 区切り文字) 指定したストリーム用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したストリーム用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれるストリーム。 /// カンマ以外の区切り文字を利用したい場合に使います。 /// stream が null です。 /// stream が読み取りをサポートしていません。 public CSVReader(System.IO.Stream stream, char 区切り文字) { if (stream == null) { throw new ArgumentNullException("stream"); } this.Init(stream); this.区切り文字 = 区切り文字; } #endregion #region public CSVReader(System.IO.TextReader reader) 指定したリーダ用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したリーダ用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込みを行うリーダ /// stream が null です。 /// stream が読み取りをサポートしていません。 public CSVReader(System.IO.TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } this.Reader = reader; } #endregion #region public CSVReader(System.IO.TextReader reader, char 区切り文字) 指定したリーダ用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したリーダ用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込みを行うリーダ /// カンマ以外の区切り文字を利用したい場合に使います。 /// stream が null です。 /// stream が読み取りをサポートしていません。 public CSVReader(System.IO.TextReader reader, char 区切り文字) { if (reader == null) { throw new ArgumentNullException("reader"); } this.Reader = reader; this.区切り文字 = 区切り文字; } #endregion #region public CSVReader(string path) 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれる完全なファイルパス。 /// path に、ファイル名、ディレクトリ名、またはボリューム ラベルとしては不正または無効な構文が含まれています。 /// path が null です。 /// path が空の文字列 ("") です。 /// 割り当てられていないドライブであるなど、指定されたパスが無効です。 /// ファイルが見つかりません。 public CSVReader(string path) { if (path == null) { throw new ArgumentNullException("path"); } this.Init(path, Encoding.UTF8); } #endregion #region public CSVReader(string path, char 区切り文字) 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれる完全なファイルパス。 /// カンマ以外の区切り文字を利用したい場合に使います。 /// path に、ファイル名、ディレクトリ名、またはボリューム ラベルとしては不正または無効な構文が含まれています。 /// path が null です。 /// path が空の文字列 ("") です。 /// 割り当てられていないドライブであるなど、指定されたパスが無効です。 /// ファイルが見つかりません。 public CSVReader(string path, char 区切り文字) { if (path == null) { throw new ArgumentNullException("path"); } this.Init(path, Encoding.UTF8); this.区切り文字 = 区切り文字; } #endregion #region public CSVReader(string path, Encoding encoding) 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれる完全なファイルパス。 /// 使用する文字エンコーディング。 /// path に、ファイル名、ディレクトリ名、またはボリューム ラベルとしては不正または無効な構文が含まれています。 /// path が null です。 /// path が空の文字列 ("") です。 /// 割り当てられていないドライブであるなど、指定されたパスが無効です。 /// ファイルが見つかりません。 public CSVReader(string path, Encoding encoding) { if (path == null) { throw new ArgumentNullException("path"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } this.Init(path, encoding); } #endregion #region public CSVReader(string path, Encoding encoding, char 区切り文字) 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 指定したファイル名用の System.IO.StreamReader を利用して新しいインスタンスを初期化します。 /// /// 読み込まれる完全なファイルパス。 /// 使用する文字エンコーディング。 /// カンマ以外の区切り文字を利用したい場合に使います。 /// path に、ファイル名、ディレクトリ名、またはボリューム ラベルとしては不正または無効な構文が含まれています。 /// path が null です。 /// path が空の文字列 ("") です。 /// 割り当てられていないドライブであるなど、指定されたパスが無効です。 /// ファイルが見つかりません。 public CSVReader(string path, Encoding encoding, char 区切り文字) { if (path == null) { throw new ArgumentNullException("path"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } this.Init(path, encoding); this.区切り文字 = 区切り文字; } #endregion #region private void Init(System.IO.Stream stream) 初期化内部処理 /// /// 初期化内部処理 /// /// 読み込まれるストリーム。 /// stream が null です。 /// stream が読み取りをサポートしていません。 private void Init(System.IO.Stream stream) { this.Reader = new System.IO.StreamReader(stream); } #endregion #region private void Init(string path, Encoding encoding) 初期化内部処理 /// /// 初期化内部処理 /// /// 読み込まれる完全なファイルパス。 /// 使用する文字エンコーディング。 /// stream が null です。 /// stream が読み取りをサポートしていません。 private void Init(string path, Encoding encoding) { this.Reader = new System.IO.StreamReader(path, encoding); } #endregion #region public void MoveNextRow() 次の行の処理に移ります。 /// /// 次の行の処理に移ります。 /// /// 次の行があればtrue public bool MoveNextRow() { while (this.行終了フラグ == false) { this.ReadColumn(); } if (this.ファイル終了フラグ == true) { return false; } else { this.行終了フラグ = false; return true; } } #endregion #region public string ReadColumn() カラムの読み出し処理を行います。 /// /// カラムの読み出し処理を行います。 /// /// 読み出したカラムの文字列 public string ReadColumn() { //行繰り越し処理が終わっていないので常に””を返す if (this.行終了フラグ == true) { return ""; } StringBuilder ReturnSB = new StringBuilder(); while (this.Reader.Peek() >= 0) { char 処理対象文字 = Convert.ToChar(this.Reader.Read()); if (ループ処理( ReturnSB, 処理対象文字)) { //ファイルの最後まで読み取っていたら終了フラグを立てる if (this.Reader.Peek() < 0) { this.行終了フラグ = true; this.ファイル終了フラグ = true; } return ReturnSB.ToString(); } } //while this.行終了フラグ = true; this.ファイル終了フラグ = true; return ReturnSB.ToString(); } #endregion #region private bool ループ処理(StringBuilder ReturnSB, char 処理対象文字) ループの実態処理 /// /// ループの実態処理 /// ループ中は区切り文字を探しつつ処理を行う /// /// 文字列抽出結果を構築するためのStringBuilder /// 処理対象の文字 /// 文字列の区切りまで到達している場合にはtrueを返す private bool ループ処理(StringBuilder ReturnSB, char 処理対象文字) { if (処理対象文字 == '\"') { //文字列処理に入ると内部で、文字列中が終了するまで読み進む 文字列中処理(ReturnSB); } else if (処理対象文字 == this.区切り文字) { //区切りなので、完了 return true; } else if (処理対象文字 == '\r') { //改行処理 char 先読み文字 = Convert.ToChar(this.Reader.Peek()); if (先読み文字 == '\n') { this.行終了フラグ = true; //空読み this.Reader.Read(); return true; } else { ReturnSB.Append(処理対象文字); } } else { ReturnSB.Append(処理対象文字); } return false; } #endregion #region private void 文字列中処理(StringBuilder ReturnSB) ダブルクォートでくくられている文字列中の処理 /// /// ダブルクォートでくくられている文字列中の処理 /// /// 文字列抽出結果を構築するためのStringBuilder private void 文字列中処理(StringBuilder ReturnSB) { while (this.Reader.Peek() >= 0) { char 処理対象文字 = Convert.ToChar(this.Reader.Read()); //ダブルクォートの場合 if (処理対象文字 == '\"') { //先読みをしてダブルクォートであれば、1つのダブルクォートを代入するが、次がダブルクォートでなければ文字列処理中断 char 先読み文字 = Convert.ToChar(this.Reader.Peek()); if (先読み文字 == '\"') { //空読み this.Reader.Read(); ReturnSB.Append("\""); } else { //文字列処理が中断 return ; } } else if (処理対象文字 == '\r') { //\rの場合次が\nの場合には先読みしておいて、\r\nを設定する。 char 先読み文字 = Convert.ToChar(this.Reader.Peek()); if (先読み文字 == '\n') { //空読み this.Reader.Read(); } ReturnSB.Append("\r\n"); } else if (処理対象文字 == '\n') { //\nだけの場合にも\r\nを設定する ReturnSB.Append("\r\n"); } else { ReturnSB.Append(処理対象文字); } } //while //文字列処理中にストリームの情報が無くなった return ; }//文字列中処理 #endregion #region 終了処理 #region public void Dispose(bool disposing) /// /// 実際の終了処理 /// /// public void Dispose(bool disposing) { if (disposing) { if (this.Reader != null) { try { this.Reader.Close(); } catch { //例外は握りつぶします。 } } } else { //try //{ // //独自ファイナライズ処理 //} //finally //{ //} } } #endregion #region public void Dispose() /// /// Dispose /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } #endregion #region ~CSVReader() /// /// デストラクタ /// 終了処理を呼び出します。 /// ~CSVReader() { this.Dispose(false); } #endregion #endregion }//class }//namespace