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