【C#】ダブルクォーテーションに対応したCSV読込処理

なんだかんだ色んなところで書いてる処理なので、いい加減メモ残しておく。
数年前に書いたやつだけど、今見るとだいぶ冗長…。

/// <summary>
/// CSVファイル読込
/// </summary>
/// <param name="filePath">CSVファイル</param>
/// <returns>データリスト</returns>
public static List ReadCSVFile(string filePath)
{
    List retList = new List();

    using (FileStream fs = new FileStream(filePath,
        FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (TextReader sr = new StreamReader(fs,
            Encoding.GetEncoding("shift-jis")))
        {
            // 内部処理変数初期化
            List tempList = new List();
            string line;
            string tempStr = "";
            bool continueFlag = false;
            int columnCount = 0;

            // 一行ずつ読み込み
            while ((line = sr.ReadLine()) != null)
            {
                // 行データをカンマ区切り
                string[] columns = line.Split(',');

                for (int i = 0; i < columns.Length; i++)
                {
                    if (columns[i].StartsWith("\"") && continueFlag == false)
                    {
                        // ダブルクォーテーションから始まる場合
                        string checkStr = columns[i].Replace("\"\"", "");
                        if (checkStr.Length == 0 || ((checkStr.Length > 2) && (checkStr.EndsWith("\""))))
                        {
                            // ダブルクォーテーションで終わればOK
                            // ダブルクォーテーションを外して格納
                            tempList.Add(columns[i].Substring(1, columns[i].Length - 2));
                        }
                        else
                        {
                            // ダブルクォーテーションで終わらない場合、継続してデータ取得
                            tempStr = columns[i];
                            continueFlag = true;
                        }
                    }
                    else
                    {
                        if (continueFlag)
                        {
                            // ダブルクォーテーション途中
                            // 終端チェック
                            string checkStr = columns[i].Replace("\"\"", "");
                            if (checkStr.EndsWith("\""))
                            {
                                // 終端である
                                if (i > 0)
                                {
                                    tempStr += "," + columns[i];
                                }
                                else
                                {
                                    tempStr += columns[i];
                                }
                                tempStr.Replace("\"\"", "\"");
                                tempList.Add(tempStr.Substring(1, tempStr.Length - 2));

                                // 一時変数クリア
                                tempStr = "";
                                continueFlag = false;
                            }
                            else
                            {
                                // 終端でない
                                if (i > 0)
                                {
                                    tempStr += "," + columns[i];
                                }
                                else
                                {
                                    tempStr += columns[i];
                                }
                                continue;
                            }
                        }
                        else
                        {
                            // ただのデータなら格納
                            tempList.Add(columns[i]);
                        }
                    }
                }

                if(continueFlag)
                {
                    // 改行で継続中
                    tempStr += "\r\n";
                }
                else
                {
                    // 1列読込完了
                    // 初回読み込みなら列数固定、2回目以降なら列数チェック
                    if (columnCount == 0)
                    {
                        columnCount = tempList.Count;
                    }
                    else
                    {
                        if(tempList.Count != columnCount)
                        {
                            // 列数が異なる場合は変換しない
                            tempList = new List();
                            continue;
                        }
                    }

                    // Listをstring配列に
                    string[] tempStrArray = new string[tempList.Count];
                    for(int i = 0; i < tempList.Count; i++)
                    {
                        tempStrArray[i] = tempList[i];
                    }

                    // string配列をリターンリストへ格納
                    retList.Add(tempStrArray);

                    // 一時変数を初期化
                    tempList = new List();
                }
            }
        }
    }

    return retList;
}

投稿者: Output48

中学生の時に初めてHTMLに触れてからホームページ制作を独学で始める。 ベンチャー企業の営業、大手企業のSEを経て、独立。 ここ数年はWEB以外の仕事をしていたため、割と本気で勉強中。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください