项目需求是读取CSV文件,在读取过程中遇到各种特殊情况,比如标题所说,回车符,在列里面出现关键符号(逗号),引号。
以下的类就是专门处理这些特殊情况的。
不喜欢讲太多废话,源码第一。
处理csv文件的类,注释没写,希望各位自己慢慢调试去理解!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Text;
namespace CSharpLight.Tool
{
public class CsvFileReader : StreamReader
{
public CsvFileReader(Stream stream)
: base(stream)
{
}
public CsvFileReader(string filePath)
: base(filePath)
{
}
public CsvFileReader(Stream stream, Encoding encoding)
: base(stream, encoding)
{
}
public CsvFileReader(string path, Encoding encoding)
: base(path, encoding)
{
}
public CsvRow ReadRow()
{
CsvRow row = new CsvRow();
int pos = 0;
bool isHasField = true;
bool isFieldStart = false;
bool isQuoteStart = false;
StringBuilder sb = new StringBuilder();
bool isBreak = false;
while (!isBreak)
{
string line = ReadLine();
if (line == null)
{
return null;
}
row.LineText += line;
int len = row.LineText.Length;
while (pos < len)
{
#region 循环判断字符
char c = row.LineText[pos];
sb.Append(c);
if (c == '"')
{
if (!isFieldStart)
{
isQuoteStart = true;
}
if (isQuoteStart)
{
isHasField = !isHasField;
}
}
if (c != ' ' && c != '\t' && c != '\n')
{
isFieldStart = true;
}
if (isHasField && (c == ',' || pos == len - 1))
{
#region 当字段结束时,处理一个字段,并且新建一个字段.
var text = sb.ToString()
.TrimEnd(',')
.Trim();
if (isQuoteStart)
{
text = text.Trim('"')
.Replace("\"\"", "\"");
}
row.Add(text);
sb = new StringBuilder();
isFieldStart = false;
isQuoteStart = false;
if (pos == len - 1)
{
isBreak = true;
}
#endregion
}
#endregion
pos++;
}
}
return row;
}
后台使用函数
/// <summary>
/// 读取csv标题行
/// </summary>
/// <param name="filePath">带文件名称的文件路径</param>
/// <param name="titleRow">是否第一行,当 titleRow = true时,则只读第一行(即标题行)</param>
/// <returns></returns>
public List<CsvRow> CSVRead(string filePath, bool titleRow)
{
List<CsvRow> vRows = new List<CsvRow>();
using (CsvFileReader reader = new CsvFileReader(filePath, Encoding.Default))
{
CsvRow row = null;
while ((row = reader.ReadRow()) != null)
{
vRows.Add(row);
if (titleRow)
{
break;
}
}
}
return vRows;
}
然后在你需要的地方调用这个函数就行了。
<span style="font-family:Arial;background-color: rgb(255, 255, 255);">如</span>
var list = CSVRead(filePath,false);