CSV分割ツールは前回で完了しましたので、今回は分割保存関数 DivideSave を別のアルゴリズムで置き換えてみたいと思います。
新しいアルゴリズムの概要
前回と今回の大きな違いですが、前回のアルゴリズムでは、ループ処理の中で行数をカウントしながら、分割行数に達した時点でファイルに保存するという方法を使いました。
今回のアルゴリズムでは、あらかじめ何分割するかを計算しておき、その分だけループするという方法を使います。
フローチャート
概要をフローチャートにまとめてみましたので、ザックリと全体の処理を確認してから、ソースコードを見て頂ければ、より理解が深まると思います。

ソースコード
DivideSave のソースコードを掲載しておきます。
前回のCSV分割ツールのDivideSave を下記のソースコードに置き換えて頂くことで、新しいアルゴリズムで動作するようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/// <summary> /// 指定行数で分割しながらファイル出力 /// </summary> /// <param name="Folder">出力先フォルダ名</param> /// <param name="fileName">CSVファイル名</param> /// <param name="headers">CSVヘッダ</param> /// <param name="lines">CSVデータ</param> /// <param name="divideCnt"></param> private void DivideSave(string Folder,string fileName,string[] headers,List<string> lines,int divideCnt) { //拡張子を除いたファイル名を取得 string name = Path.GetFileNameWithoutExtension(fileName); //ファイル名から拡張子のみを取得 string ext = Path.GetExtension(fileName); //分割ページ数 int page = (lines.Count / divideCnt) + 1; //全体の行数 int len = lines.Count; //ループ処理 for(int i = 0;i < page;i ++) { //出力パス(フォルダ名+ファイル名+連番+拡張子)のテンプレートを作成 string template = Path.Combine(Folder, name + "{0}" + ext); //出力ファイル名を作成 string path = string.Format(template, i); //取り出し可能な行数を算定(上限は分割行数) int size = (len < divideCnt) ? len : divideCnt; //全体の行数から今回取り出す行数を引く len -= divideCnt; //ファイル保存に用いる変数(配列)を確保 string[] buff = new string[size + headers.Length]; //変数にヘッダをコピー headers.CopyTo(buff, 0); //行を取り出し、変数にコピー(先頭はヘッダなので、ヘッダの次の位置にコピー) lines.CopyTo(i * size ,buff, headers.Length, size); //ファイル保存 File.WriteAllLines(path,buff, Encoding.GetEncoding("shift-jis")); } } |
DivideSave の置き換えが面倒な方は、今回のアルゴリズムに置き換えたCSV分割ツールのプロジェクトを下記からダウンロードして頂けますので、ご利用ください。
まとめ
今回は以上になります。
DivideSave を全く別のアルゴリズムで置き換えてみました。
他にもいろいろなアルゴリズムがありますので、一度考えて見られてはどうでしょう。
勉強になると思います。
また、今回を通して関数化(メソッド化)のメリットもご理解いただけたかと思います。
次回は、最初のCSV分割ツールのソースコードを、C#っぽい書き方で書き直しててみたいと思います。