我是C#的学习者。我想从CSV文件中读取特定值。我已经学会了通过浏览将csv文件转换为数据表。请参阅以下代码(感谢surendra jha)和我的CSV文件格式。说,我想得到'ID'= 90的'音量'。
CSV文件
ID:Volume:Name
100:5600:A
95:5000:B
90:4500:C
85:4000:D
获取所有值的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
namespace DVHConsolePrj
{
class Program
{
static void Main(string[] args)
{
readCsvFileData();
}
static void readCsvFileData()
{
string path = @"C:\IDVolumeName.txt";
StreamReader streamreader = new StreamReader(path);
DataTable datatable = new DataTable();
int rowcount = 0;
string[] columnname = null;
string[] streamdatavalue = null;
while (!streamreader.EndOfStream)
{
string streamrowdata = streamreader.ReadLine().Trim();
if (streamrowdata.Length > 0)
{
streamdatavalue = streamrowdata.Split(':');
if (rowcount == 0)
{
rowcount = 1;
columnname = streamdatavalue;
foreach (string csvheader in columnname)
{
DataColumn datacolumn = new DataColumn(csvheader.ToUpper(), typeof(string));
datacolumn.DefaultValue = string.Empty;
datatable.Columns.Add(datacolumn);
}
}
else
{
DataRow datarow = datatable.NewRow();
for (int i = 0; i < columnname.Length; i++)
{
datarow[columnname[i]] = streamdatavalue[i] == null ? string.Empty : streamdatavalue[i].ToString();
}
datatable.Rows.Add(datarow);
}
}
}
streamreader.Close();
streamreader.Dispose();
foreach (DataRow dr in datatable.Rows)
{
string rowvalues = string.Empty;
foreach (string csvcolumns in columnname)
{
rowvalues += csvcolumns + "=" + dr[csvcolumns].ToString() + " ";
}
Console.WriteLine(rowvalues);
}
Console.ReadLine();
}
}
}
答案 0 :(得分:1)
public DataTable CSVToDataTable(string filename, string separator)
{
try
{
FileInfo file = new FileInfo(filename);
OleDbConnection con =
new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" +
file.DirectoryName + "\";
Extended Properties='text;HDR=Yes;FMT=Delimited(" + separator + ")';")
OleDbCommand cmd = new OleDbCommand(string.Format
("SELECT * FROM [{0}]", file.Name), con);
con.Open();
DataTable tbl = new DataTable();
using (OleDbDataAdapter adp = new OleDbDataAdapter(cmd))
{
tbl = new DataTable("MyTable");
adp.Fill(tbl);
}
return tbl;
}
catch(Exception ex)
{
throw ex;
}
finally()
{
con.Close();
}
}
您可以尝试使用此代码,它是即时构建的,可能存在很少的错误。检查OleDbConnection。当您返回DataTable时,您可以使用LINQ在表中搜索。
var results = from myRow in myDataTable.AsEnumerable()
where myRow.Field<int>("ID") == 90
select myRow;
在这里你可以拿ID = 90的行!
答案 1 :(得分:1)
不是在DataTable中手动解析文件,而是在做一些Linq,使用this library直接在其上使用Linq。
效果非常好,并且对大文件非常有效。
例如。
1)在您的项目中添加nuget包,以及以下行以便能够使用它:
using LINQtoCSV;
2)定义旧数据的类
public class IdVolumeNameRow
{
[CsvColumn(FieldIndex = 1)]
public string ID { get; set; }
[CsvColumn(FieldIndex = 2)]
public decimal Volume { get; set; }
[CsvColumn(FieldIndex = 3)]
public string Name{ get; set; }
}
3)并搜索值
var csvAttributes = new CsvFileDescription
{
SeparatorChar = ':',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var volume = cc.Read<IdVolumeNameRow>(@"C:\IDVolumeName.txt", csvAttributes)
.Where(i => i.ID == "90")
.Select(i => i.Volume)
.FirstOrDefault();
答案 2 :(得分:0)
对于过滤DataTable,您可以使用{/ 3}}这样的方法
var filtered = dataTable.Select("ID = '90'");
上面的 filtered
是适合条件的数据行数组,因此要从第一个过滤行获取值,您可以使用类似
if(filtered.Length>0){
var Volume = filtered[0]["VOLUME"];
}