将IEnumerable字符串数组转换为datatable

时间:2014-11-13 09:40:43

标签: c# asp.net .net linqtocsv

我有一个用pipe(|)分隔的csv文件。我正在使用以下代码行阅读它:

IEnumerable<string[]> lineFields = File.ReadAllLines(FilePath).Select(line => line.Split('|'));

现在,我需要将其绑定到GridView。所以我创建了一个动态DataTable,如下所示:

DataTable dt = new DataTable();
int i = 0;
foreach (string[] order in lineFields)
{
    if (i == 0)
    {                        
        foreach (string column in order)
        {
            DataColumn _Column = new DataColumn();
            _Column.ColumnName = column;
            dt.Columns.Add(_Column);
            i++;
            //Response.Write(column);
            //Response.Write("\t");
        }
    }
    else
    {
        int j = 0;
        DataRow row = dt.NewRow();
        foreach (string value in order)
        {
            row[j] = value;                            
            j++;

            //Response.Write(column);
            //Response.Write("\t");
        }
        dt.Rows.Add(row);
    }
    //Response.Write("\n");
}

这很好用。但我想知道是否有更好的方法可以将IEnumerable<string[]>转换为DataTable。我需要读取这样的许多CSV,所以我认为上面的代码可能存在性能问题。

2 个答案:

答案 0 :(得分:2)

从.Net 4开始:

使用ReadLines

DataTable FileToDataTable(string FilePath)
{

    var dt = new DataTable();

    IEnumerable<string[]> lineFields = File.ReadLines(FilePath).Select(line => line.Split('|'));
    dt.Columns.AddRange(lineFields.First().Select(i => new DataColumn(i)).ToArray());

    foreach (var order in lineFields.Skip(1))
        dt.Rows.Add(order);

    return dt;
}

编辑:代替此代码,使用@Jodrell的代码回答,这可以防止对枚举器进行双重充电。)

在.Net 4之前:

使用流媒体:

DataTable FileToDataTable1(string FilePath)
{
    var dt = new DataTable();

    using (var st = new StreamReader(FilePath))
    {
        // first line procces
        if (st.Peek() >= 0)
        {
            var order = st.ReadLine().Split('|');
            dt.Columns.AddRange(order.Select(i => new DataColumn(i)).ToArray());
        }

        while (st.Peek() >= 0)
            dt.Rows.Add(st.ReadLine().Split('|'));
    }
    return dt;
}

答案 1 :(得分:1)

因为,在您的链接示例中,该文件有一个标题行。

const char Delimiter = '|';

var dt = new DataTable;
using (var m = File.ReadLines(filePath).GetEnumerator())
{
    m.MoveNext();
    foreach (var name in m.Current.Split(Delimiter))
    {
        dt.Columns.Add(name);
    }

    while (m.MoveNext())
    {
        dt.Rows.Add(m.Current.Split(Delimiter));
    }
}

一次性读取文件