C# 用C语言读取CSV文件#

C# 用C语言读取CSV文件#,c#,open-source,csv,C#,Open Source,Csv,有谁知道有一个开源库允许您解析和读取C#中的.csv文件吗?请看一下CodeProject。这里是您为真正使用通用集合和迭代器块而编写的。它支持使用双转义约定的双引号括起的文本字段(包括跨多行的文本字段)(因此引号内的“读取为单引号字符)。它不支持: 单引号封闭文本 \-转义引用文本 备用分隔符(在管道或制表符分隔的字段上还不起作用) 以引号开头的非引号文本字段 但如果你需要的话,所有这些都很容易添加。我还没有在任何地方对它进行基准测试(我很想看到一些结果),但性能应该非常好-无论如何都比基

有谁知道有一个开源库允许您解析和读取C#中的
.csv
文件吗?

请看一下CodeProject。

这里是您为真正使用通用集合和迭代器块而编写的。它支持使用双转义约定的双引号括起的文本字段(包括跨多行的文本字段)(因此引号内的
读取为单引号字符)。它不支持:

  • 单引号封闭文本
  • \-转义引用文本
  • 备用分隔符(在管道或制表符分隔的字段上还不起作用)
  • 以引号开头的非引号文本字段
但如果你需要的话,所有这些都很容易添加。我还没有在任何地方对它进行基准测试(我很想看到一些结果),但性能应该非常好-无论如何都比基于
.Split()
的任何东西都好

更新:想要添加单引号括起来的文本支持。这是一个简单的更改,但我在回复窗口中输入了它,因此它未经测试。如果您喜欢旧的(测试过的)代码,请使用底部的修订链接

公共静态类CSV
{
公共静态IEnumerable FromFile(字符串文件名,bool ignoreFirstLine=false)
{
使用(StreamReader rdr=新StreamReader(文件名))
{
foreach(FromReader中的IList项(rdr,ignoreFirstLine))生成返回项;
}
}
公共静态IEnumerable FromStream(流csv,bool ignoreFirstLine=false)
{
使用(var rdr=新的StreamReader(csv))
{
foreach(FromReader中的IList项(rdr,ignoreFirstLine))生成返回项;
}
}
公共静态IEnumerable FromReader(TextReader csv,bool ignoreFirstLine=false)
{
if(ignoreFirstLine)csv.ReadLine();
IList结果=新列表();
StringBuilder曲线值=新的StringBuilder();
字符c;
c=(char)csv.Read();
而(csv.Peek()!=-1)
{
开关(c)
{
大小写“,”://空字段
结果:添加(“”);
c=(char)csv.Read();
打破
大小写“'://限定文本
案例'\'':
char q=c;
c=(char)csv.Read();
bool-inQuotes=true;
while(inQuotes&&csv.Peek()!=-1)
{
如果(c==q)
{
c=(char)csv.Read();
如果(c!=q)
inQuotes=false;
}
如果(以引号引)
{
曲线值。附加(c);
c=(char)csv.Read();
} 
}
result.Add(curValue.ToString());
曲线值=新的StringBuilder();
如果(c==',')c=(char)csv.Read();//或者',',换行符,或者endofstream
打破
案例'\n'://记录的结尾
案例'\r':
//这里的潜在错误取决于换行符的外观
if(result.Count>0)//不返回空记录
{
收益结果;
结果=新列表();
}
c=(char)csv.Read();
打破
默认值://normal非限定文本
而(c!='、'&&c!='\r'&&c!='\n'&&csv.Peek()!=-1)
{
曲线值。附加(c);
c=(char)csv.Read();
}
result.Add(curValue.ToString());
曲线值=新的StringBuilder();
如果(c==',')c=(char)csv.Read();//或者',',换行符,或者endofstream
打破
}
}
if(curValue.Length>0)//潜在错误:如果调用方真的希望最后一条记录中的空列出现,我不想跳过它
result.Add(curValue.ToString());
如果(result.Count>0)
收益结果;
}
}
我真的很喜欢这个库。它速度快,是C#100%,免费提供,非常灵活且易于使用。

我给出了:

如果您只是尝试使用C#读取CSV文件,最简单的方法是使用该类。它实际上内置在.NET Framework中,而不是作为第三方扩展

是的,它位于Microsoft.VisualBasic.dll中,但这并不意味着不能从C#(或任何其他CLR语言)使用它

下面是一个使用示例,摘自:


同样,这个示例在VB.NET中,但是将其转换为C#是很简单的。

除了解析/读取之外,一些库还可以为您做其他很好的事情,比如将解析后的数据转换为对象

下面是一个使用(我维护的库)将CSV文件读入对象的示例

var csv = new CsvHelper( File.OpenRead( "file.csv" ) );
var myCustomObjectList = csv.Reader.GetRecords<MyCustomObject>();
有时您并不“拥有”要填充数据的对象。在这种情况下,您可以使用fluent类映射

// Fluent class mapping:
public sealed class MyCustomObjectMap : CsvClassMap<MyCustomObject>
{
    public MyCustomObjectMap()
    {
        Map( m => m.StringProperty ).Name( "First Name" );
        Map( m => m.IntProperty ).Index( 0 );
        Map( m => m.ShouldIgnore ).Ignore();
    }
}
//Fluent类映射:
公共密封类MyCustomObjectMap:CsvClassMap
{
公共MyCustomObjectMap()
{
Map(m=>m.StringProperty).Name(“名字”);
Map(m=>m.IntProperty).Index(0);
Map(m=>m.ShouldIgnore).Ignore();
}
}

我正在用C#实现Daniel Pryden的答案,因此更容易剪切、粘贴和自定义。我认为这是解析CSV文件的最简单方法。只需添加一个引用,您就基本完成了

Microsoft.VisualBasic
引用添加到项目中

下面是Joel用C#编写的示例代码
var csv = new CsvHelper( File.OpenRead( "file.csv" ) );
var myCustomObjectList = csv.Reader.GetRecords<MyCustomObject>();
// Using attributes:
public class MyCustomObject
{
    [CsvField( Name = "First Name" )]
    public string StringProperty { get; set; }

    [CsvField( Index = 0 )]
    public int IntProperty { get; set; }

    [CsvField( Ignore = true )]
    public string ShouldIgnore { get; set; }
}
// Fluent class mapping:
public sealed class MyCustomObjectMap : CsvClassMap<MyCustomObject>
{
    public MyCustomObjectMap()
    {
        Map( m => m.StringProperty ).Name( "First Name" );
        Map( m => m.IntProperty ).Index( 0 );
        Map( m => m.ShouldIgnore ).Ignore();
    }
}
using (Microsoft.VisualBasic.FileIO.TextFieldParser MyReader = new           
       Microsoft.VisualBasic.FileIO.TextFieldParser(filename))
{
    MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
    MyReader.SetDelimiters(",");

    while (!MyReader.EndOfData)
    {
        try
        {
            string[] fields = MyReader.ReadFields();
            if (first) 
            {
                first = false;
                continue;
            }

            // This is how I treat my data, you'll need to throw this out.

            //"Type"    "Post Date" "Description"   "Amount"
            LineItem li = new LineItem();

            li.date        = DateTime.Parse(fields[1]);
            li.description = fields[2];
            li.Value       = Convert.ToDecimal(fields[3]);

            lineitems1.Add(li);
        }
        catch (Microsoft.VisualBasic.FileIO.MalformedLineException ex)
        {
            MessageBox.Show("Line " + ex.Message + 
                            " is not valid and will be skipped.");
        }
    }
}
static void Main()
        {
            string csv_file_path=@"C:\Users\Administrator\Desktop\test.csv";

            DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);

            Console.WriteLine("Rows count:" + csvData.Rows.Count);

            Console.ReadLine();
        }


private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
        {
            DataTable csvData = new DataTable();

            try
            {

            using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
                {
                    csvReader.SetDelimiters(new string[] { "," });
                    csvReader.HasFieldsEnclosedInQuotes = true;
                    string[] colFields = csvReader.ReadFields();
                    foreach (string column in colFields)
                    {
                        DataColumn datecolumn = new DataColumn(column);
                        datecolumn.AllowDBNull = true;
                        csvData.Columns.Add(datecolumn);
                    }

                    while (!csvReader.EndOfData)
                    {
                        string[] fieldData = csvReader.ReadFields();
                        //Making empty value as null
                        for (int i = 0; i < fieldData.Length; i++)
                        {
                            if (fieldData[i] == "")
                            {
                                fieldData[i] = null;
                            }
                        }
                        csvData.Rows.Add(fieldData);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return csvData;
        }