近期都在处理淘宝商品数据包识别问题,满以为CSV文件就是以行为分割,以逗号为字段分割的文件体系。
自己在编写处理程序时,增加了2个参数: 第一个,字符集,第二,告知处理方法,文件的列在第几行。
同时,对某些生成出来的数据包不规据的,例如生成出2个同名列的,等等文件,做了一定的容错。
满以为这样就OK了,没想到,老革命遇上新问题。原来 CSV文件中还是有转义的,引号即是。这一个处理,导致
程序出现了严重BUG,有一批数据包无法识别。。。。
现程序已经优化过。本CSV阅读程序,直接将CSV文件转换成TABLE格式,可以识别引号,可以识别在字符串中的回车,比一般网上查找的CSV文件
阅读程序要好,我试过,基本和WPS(我机器上没装OFFICE)容错能力一致。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace test
{
public class JHCSV
{
public static DataTable LoadCsv(string filename, System.Text.Encoding encoder, char pfix, int headerLineIndex)
{
List<string> dataList = getData(filename, encoder);
DataTable dt = Getdt(dataList, headerLineIndex, pfix);
for (int i = headerLineIndex + 1; i < dataList.Count; i++)
{
if (dataList[i].Trim().Equals(""))
{
continue;
}
else
{
DataRow dr = dt.NewRow();
ReadLine(ref dr, dataList[i], pfix);
dt.Rows.Add(dr);
}
}
return dt;
}
private static DataRow ReadLine(ref DataRow dr, string line, char pfix)
{
string[] data = line.Split(new char[] { pfix });
StringBuilder ValueBuffer = new StringBuilder("");
int columnIndex = 0;
foreach (string str in data)
{
ValueBuffer.Append(str);
if (checkyh(ValueBuffer.ToString(), ‘"‘))
{
ValueBuffer = ValueBuffer.Replace("\"\"", "\"");
if (columnIndex < dr.Table.Columns.Count)
{
dr[columnIndex] = ValueBuffer.ToString().TrimStart(‘"‘).TrimEnd(‘"‘);
columnIndex++;
ValueBuffer.Clear();
}
else
{
Console.WriteLine(ValueBuffer.ToString());
ValueBuffer.Clear();
continue;
}
}
else
{
ValueBuffer.Append(pfix);
}
}
return dr;
}
private static DataTable Getdt(List<string> data, int headIndex, char pfix)
{
DataTable dt = new DataTable();
string[] columns = data[headIndex].Split(new char[] { pfix });
foreach (string columnname in columns)
{
if (columnname.Equals(""))
{
continue;
}
else
{
if (dt.Columns[columnname] != null)
{
dt.Columns.Add(columnname + "1");
}
else
{
dt.Columns.Add(columnname);
}
}
}
return dt;
}
private static List<string> getData(string filename, System.Text.Encoding encoder)
{
System.IO.StreamReader sr = new System.IO.StreamReader(filename, encoder);
List<string> dataList = new List<string>();
string line = sr.ReadLine();
System.Text.StringBuilder lineBuffer = new StringBuilder("");
while (line != null)
{
lineBuffer.Append(line);
if (checkyh(lineBuffer.ToString(),‘\"‘))
{
dataList.Add(lineBuffer.ToString());
lineBuffer = new StringBuilder("");
}
line = sr.ReadLine();
}
sr.Close();
return dataList;
}
public static bool checkyh(string str,char cp)
{
int i = 0;
foreach (char c in str)
{
if(c==‘\"‘)
{
i++;
}
}
if (i % 2 == 0)
{
return true;
}
else
{
return false;
}
}
}
}