波斯马BOSSMA Information Technology

C#下的CSV文件读取利器-CSVReader

发布时间:2011年5月27日 / 分类:DOTNET / 34,358 次浏览 / 评论

在c#中读取csv文件可以使用OLEDB当作数据库来读取,或者一行行的读取,然后使用正则表达式进行解析。使用oledb一般情况下也比较方便,但是效率不是很好,特别是csv文件很大的情况下。如果一行行的读取,对数据字段进行拆分是个难题,一般情况下使用英文逗号就可以了,但是很多情况下字段的内容也都包含了逗号,还有可能一条数据要占用多行。今天推荐一个别人封装好的csv读取类库:CSVReader,可以快速方便的处理csv数据。

类库作者开发这个程序经历了很多年了,最近还在更新中。点击下面的地址到官方网站:
http://www.codeproject.com/KB/database/CsvReader.aspx

这个程序的最大特点是速度快,按照作者的说法比使用OLEDB正则表达式的方法大约快15倍,而且内存使用较少。举一个例子,在CPU P4 3.0 GHz, 内存1024 MB的电脑上,一个45M的csv文件,145个字段,5万条记录,用时大约1.5秒,每秒钟处理大约30M数据。当然肯定不是每次都这么快,影响的因素比较多,咱也不要较真。

这个程序还有一个特点是可以处理多行数据,前提是数据必须引用起来。

这个程序本质上也是按行读取的,在读取的时候会为当前记录保存一个字段缓存。作者还提供了一个类CachedCsvReader会将csv文件内容全部缓存到内存,然后从缓存中读取。

说了这么多,看看例子吧:
1、基本用法

using System.IO;
using LumenWorks.Framework.IO.Csv;

void ReadCsv()
{
// 打开"data.csv" ,这个csv文件应该有一个标题行
using (CsvReader csv =
new CsvReader(new StreamReader("data.csv"), true))
{
//字段数量
int fieldCount = csv.FieldCount;
//标题数组
string[] headers = csv.GetFieldHeaders();
//只进的游标读取
while (csv.ReadNextRecord())
{
//遍历列
for (int i = 0; i < fieldCount; i++)
Console.Write(string.Format("{0} = {1};",
headers[i], csv[i]));

Console.WriteLine();
}
}
}

2、简单数据绑定(ASP.NET)

using System.IO;
using LumenWorks.Framework.IO.Csv;

void ReadCsv()
{
// 打开"data.csv" ,这个csv文件应该有一个标题行
using (CsvReader csv = new CsvReader(
new StreamReader("data.csv"), true))
{
myDataRepeater.DataSource = csv;
myDataRepeater.DataBind();
}
}

对于DataGrid和GridView不能使用,原因是效率问题和控件的内部机制无法满足。具体说明看上边提供的网址。
3、复杂数据绑定(Windows Forms)

using System.IO;
using LumenWorks.Framework.IO.Csv;

void ReadCsv()
{
??? // 打开"data.csv" ,这个csv文件应该有一个标题行
??? using (CachedCsvReader csv = new
?????????? CachedCsvReader(new StreamReader("data.csv"), true))
??? {
??????? //?字段 标题将自动作为列的名称
??????? myDataGrid.DataSource = csv;
??? }
}

4、自定义错误处理

using System.IO;
using LumenWorks.Framework.IO.Csv;

void ReadCsv()
{
??? //??打开"data.csv" ,这个csv文件应该有一个标题行
??? using (CsvReader csv = new CsvReader(
?????????? new StreamReader("data.csv"), true))
??? {
??????? // 丢失的字段将不会抛出异常,而被当作一个null值处理
??????? csv.MissingFieldAction = MissingFieldAction.ReplaceByNull;

??????? // 丢失的字段将不会抛出异常,而被当作一个null值处理
??????? //csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;

??????? int fieldCount = csv.FieldCount;
??????? string[] headers = csv.GetFieldHeaders();

??????? while (csv.ReadNextRecord())
??????? {
??????????? for (int i = 0; i < fieldCount; i++)
??????????????? Console.Write(string.Format("{0} = {1};",
????????????????????????????? headers[i],
????????????????????????????? csv[i] == null ? "MISSING" : csv[i]));

??????????? Console.WriteLine();
??????? }
??? }
}

5、自定义错误触发事件

using System.IO;
using LumenWorks.Framework.IO.Csv;

void ReadCsv()
{
??? // open the file "data.csv" which is a CSV file with headers
??? using (CsvReader csv = new CsvReader(
?????????? new StreamReader("data.csv"), true))
??? {
??????? //?格式化字段出错时,触发事件csv_ParseError

???????csv.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
??????? csv.ParseError += new ParseErrorEventHandler(csv_ParseError);

??????? int fieldCount = csv.FieldCount;
??????? string[] headers = csv.GetFieldHeaders();

??????? while (csv.ReadNextRecord())
??????? {
??????????? for (int i = 0; i < fieldCount; i++)
??????????????? Console.Write(string.Format("{0} = {1};",
????????????????????????????? headers[i], csv[i]));

??????????? Console.WriteLine();
??????? }
??? }
}

void csv_ParseError(object sender, ParseErrorEventArgs e)
{
??? // 如果错误是字段不存在,则跳转到下一行
??? if (e.Error is MissingFieldCsvException)
??? {
??????? Console.Write("--MISSING FIELD ERROR OCCURRED");
??????? e.Action = ParseErrorAction.AdvanceToNextLine;
??? }
}

使用起来还是挺方便的,赶紧试试吧。

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯马,原文地址《C#下的CSV文件读取利器-CSVReader

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】 【下一篇】

目前有4 条评论

  1. csv 0楼:

    请问如何把读取后的csv内容保存到DataTable中。

  2. postreetboy 0楼:

    为什么运行之后在datagridview上没有显示,但又能正常运行,请问有完整的例子吗?谢谢

  3. ant 0楼:

    @aaa

    中文是沒問題的
    在StreamReader 加 Encoding 即可:

    using (CsvReader csv = new CsvReader(
    new StreamReader(“data.csv”, Encoding.Default, true), true))
    {
    ….

  4. aaa 0楼:

    试用了,可惜不能处理中文,中文是乱码呢

发表评论