CSV文件读取类

来源:互联网 发布:php switch case语句 编辑:程序博客网 时间:2024/05/20 23:39

 public class CSVReader
    {
        private static int GetCsvSymbolClass(int c, char spliter)
        {
            if (c == (int)spliter)
                return 1;


            switch (c)
            {
                case '"':
                    return 2;
                case '\r':
                    return 3;
                case '\n':
                    return 4;
                case -1:
                    return 5;
            }
            return 0;
        }


        /*
                  0       1       2    3      4    5
        symbol \other  \spliter  '"'  '\r'  '\n'  \eof  
        status
        0  1  0  2   3 5   5
        1  1  0  2   3 5   5
        2  2  2  4   2 2   6
        3  1  0  2   3 5   5
        4  1  0  2   3 5   5
        5 complete status
        6 error status
        */
        static int[,] CsvStatusTable = new int[,]{
        {1,0,2,3,5,5},
        {1,0,2,3,5,5},
        {2,2,4,2,2,6},
        {1,0,2,3,5,5},
        {1,0,2,3,5,5}
    };


        delegate bool CsvAcceptorHandler(int index, string s);


        private static bool CsvLineSplit(TextReader r, char spliter, CsvAcceptorHandler acceptor)
        {
            int cTmp;
            int iSymbolClass = GetCsvSymbolClass(cTmp = r.Read(), spliter);
            if (iSymbolClass == 5)
                return false;


            StringBuilder strTmp = new StringBuilder();
            int index = 0;
            int iCsvStatus = 0;
            bool isNull = true;


            while (true)
            {
                switch (6 * iCsvStatus + iSymbolClass)
                {
                    case 18:
                        strTmp.Append('\r');
                        goto case 26;
                    case 0:
                    case 6:
                    case 12:
                    case 13:
                    case 15:
                    case 16:
                    case 24:
                    case 26:        //cTmp = '"'
                        strTmp.Append((char)cTmp);
                        break;
                    case 1:
                        if (!acceptor(index++, null))
                            return false;
                        isNull = true;
                        strTmp.Length = 0;
                        break;
                    case 19:
                        strTmp.Append('\r');
                        goto case 25;
                    case 7:
                    case 25:
                        if (!acceptor(index++, isNull && strTmp.Length == 0 ? null : strTmp.ToString()))
                            return false;
                        isNull = true;
                        strTmp.Length = 0;
                        break;
                    case 20:
                    case 21:
                        strTmp.Append('\r');
                        break;
                    case 2:
                    case 8:
                    case 14:
                        isNull = false;
                        goto case 27;
                    case 3:
                    case 9:
                    case 27:
                        break;
                    case 4:
                    case 5:
                        return acceptor(index++, null);
                    case 23:
                        strTmp.Append('\r');
                        goto case 29;
                    case 10:
                    case 11:
                    case 22:
                    case 28:
                    case 29:
                        return acceptor(index++, isNull && strTmp.Length == 0 ? null : strTmp.ToString());
                    case 17:
                        return false;
                }


                iCsvStatus = CsvStatusTable[iCsvStatus, iSymbolClass];
                iSymbolClass = GetCsvSymbolClass(cTmp = r.Read(), spliter);
            }
        }


        static int column;
        static int row;
        static List<string> list;
        static DataTable dt;
        static DataRow dataRow;
        private static bool CsvFieldHandler(int index, string s)
        {


            if (row == 0)
            {
                s = s.Replace(" ", "");
                column++;
                list.Add(s);


            }
            if (row == 1 && index == 0)
            {
                s = s.Replace(" ", "");
                //生成列
                for (int i = 0; i < list.Count; i++)
                {
                    dt.Columns.Add(list[i].Trim());
                }
            }
            if (row > 0)
            {
                //把第一行数据添加到表里
                if (index == 0)
                {
                    dataRow = dt.NewRow();
                    dataRow[index] = s;
                }
                else
                {
                    dataRow[index] = s;


                }
                if (index == column - 1)
                {
                    dt.Rows.Add(dataRow);
                }
            }
            //Console.Write(s);
            //Console.Write("\t");
            return true;
        }


        public static DataTable Load(string path)
        {
            column = 0;
            row = 0;
            list = new List<string>();
            dt = new DataTable();
            using (TextReader r = new StreamReader(path, Encoding.GetEncoding(936)))
            {
                DateTime dtS = DateTime.Now;
                while (CsvLineSplit(r, ',', new CsvAcceptorHandler(CsvFieldHandler)))
                {
                    row++;
                    //Console.Write(column.ToString());
                    //Console.WriteLine();
                }
                return dt;
            }
        }
        /// <summary>
        /// 程序执行时间测试
        /// </summary>
        /// <param name="dateBegin">开始时间</param>
        /// <param name="dateEnd">结束时间</param>
        /// <returns>返回(秒)单位,比如: 0.00239秒</returns>
        public static string ExecDateDiff(DateTime dateBegin, DateTime dateEnd)
        {
            TimeSpan ts1 = new TimeSpan(dateBegin.Ticks);
            TimeSpan ts2 = new TimeSpan(dateEnd.Ticks);
            TimeSpan ts3 = ts1.Subtract(ts2).Duration();
            //你想转的格式
            return ts3.TotalMinutes.ToString();
        }
    }

原创粉丝点击