CSV文档规则
1:数据使用逗号分隔;
2:内容中可以包括用于分隔数据的逗号,此类数据使用双引号括起;
3:数据中如果包括双引号,需要使用两个双引号;
代码中没有使用Remove和Substring等函数对源串进行处理,而是使用了索引来定位字符串值。
下面的代码将CSV文件解释出的数据存放到DataTable中以便使用。附计算的活动图。
/// <summary>
/// csv文件解释
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCallcsv_Click(object sender, EventArgs e)
{
FileStream fileStream = new FileStream(@"D:\temp\a.csv", FileMode.Open, FileAccess.Read, FileShare.None);
//标识读取的是否是第一行,第一行是列名
bool columnFlag = true;
//定义新数据行
string strLine = null;
DataTable table = new DataTable();
using (StreamReader sr = new StreamReader(fileStream, System.Text.Encoding.GetEncoding("gb2312")))
{
while (!mysr.EndOfStream)
{
strLine = mysr.ReadLine();
if (!string.IsNullOrEmpty(strLine))
{
//lihx 2013年4月7日 实际上这里会有问题,因为CSV中,使用“”括起来的内容包括“,”的时候,逗号不被解释为分隔符,比如:“"2-邮局汇款,"”
//读取第一行,作为列名
if (columnFlag)
{
columnFlag = false;
int lineStartIndex = 0;
while (lineStartIndex < strLine.Length)
{
table.Columns.Add(getSPValue(sr, ref lineStartIndex, ref strLine));
}
}
else
{
//初始化新行,并放入table中
int itemIndex = 0;
int lineStartIndex = 0;
object[] items = new object[table.Columns.Count];
while (lineStartIndex < strLine.Length && itemIndex < items.Length)
{
items[itemIndex++] = getSPValue(sr, ref lineStartIndex, ref strLine);
}
table.Rows.Add(items);
}
}
}
}
}
}
private static string getSPValue(StreamReader sr, ref int lineStartIndex, ref string strLine)
{
int spIndex = lineStartIndex;
if (lineStartIndex >= strLine.Length)
{
return string.Empty;
}
if (strLine[spIndex] == '\"')
{
lineStartIndex++;
int tmpIndex = -1;
while ((tmpIndex = strLine.IndexOf("\"", spIndex + 1)) == -1)
{
string nextLine = sr.ReadLine();
strLine += "\n" + nextLine;
}
spIndex = tmpIndex;
if (spIndex == -1)
{
spIndex = strLine.Length;
}
}
spIndex = strLine.IndexOf(",", spIndex);
if (spIndex == -1)
{
spIndex = strLine.Length;
}
if (lineStartIndex > -1 && lineStartIndex < strLine.Length)
{
string tmpValue = strLine.Substring(lineStartIndex, spIndex - lineStartIndex);
if (tmpValue != null && tmpValue.Length > 1 && tmpValue.StartsWith("\"") && tmpValue.EndsWith("\""))
{
tmpValue = tmpValue.Substring(1, tmpValue.Length - 2);
if (tmpValue.Length > 0)
{
tmpValue = tmpValue.Replace("\"\"", "\"");
}
}
//考虑到性能不建议使用以下截串的算法。
//strline = strline.Substring(spIndex + 1);
lineStartIndex = spIndex + 1;
return tmpValue;
}
lineStartIndex = spIndex + 1;
return string.Empty;
}