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();
}
}
CSV文件读取类
最新推荐文章于 2022-02-27 18:59:41 发布