#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