使用Jet读取CSV文件 - 制表符分隔不起作用!

时间:2010-02-24 18:19:17

标签: c#

这一直在杀我 - 我有一个庞大的文件,我需要以DataTable的形式阅读。

在经历了很多混乱之后我正在使用它:

using (OleDbConnection connection = new OleDbConnection(connString))
{
    using (OleDbCommand command = new OleDbCommand(sql, connection))
    {
        using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
        {
            dataTable = new DataTable();
            dataTable.Locale = CultureInfo.CurrentCulture;
            adapter.Fill(dataTable);
        }
    }
}

如果文本文件是逗号分隔的,但如果它是制表符分隔的则不起作用,这是有效的 - 有人可以帮忙吗?

我的连接字符串如下:

string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + @";Extended Properties='text;HDR=YES'";

我试图设置FMT属性没有运气....

3 个答案:

答案 0 :(得分:2)

这是一个很好的图书馆使用它。

http://www.codeproject.com/KB/database/CsvReader.aspx

以下是使用该库的代码。

TextReader tr = new StreamReader(HttpContext.Current.Server.MapPath(Filename));
string data = tr.ReadToEnd();
tr.Close();

以逗号分隔;

CachedCsvReader cr = new CachedCsvReader(new StringReader(csv), true);

用于制表符分隔;

CachedCsvReader cr = new CachedCsvReader(new StringReader(csv), true, '\t');

在这里,您可以通过此代码将其加载到 DataTable

DataTable dt = new DataTable();
dt.Load(cr);

希望你觉得它有用。感谢

答案 1 :(得分:0)

手动:您可以使用String.Split()方法拆分整个文件。这是我在代码中使用的示例。在这个例子中,我逐行读取数据并将其拆分。然后我将数据直接放入列中。

                //Open and read the file
                System.IO.FileStream fs = new System.IO.FileStream("myfilename", System.IO.FileMode.Open);
                System.IO.StreamReader sr = new System.IO.StreamReader(fs);

                string line = "";
                line = sr.ReadLine();

                string[] colVal;

                try
                {
                    //clear of previous data
                    //myDataTable.Clear();

                    //for each reccord insert it into a row
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();

                            colVal = line.Split('\t');

                            DataRow dataRow = myDataTable.NewRow();

                            //associate values with the columns
                            dataRow["col1"] = colVal[0];        
                            dataRow["col2"] = colVal[1]; 
                            dataRow["col3"] = colVal[2]; 

                            //add the row to the table
                            myDataTable.Rows.Add(dataRow);
                    }

                    //close the stream
                    sr.Close();

                    //binds the dataset tothe grid view.
                    BindingSource bs = new BindingSource();
                    bs.DataSource = myDataSet;
                    bs.DataMember = myDataTable.TableName;
                    myGridView.DataSource = bs;
                }

你可以修改它,为列做一些循环,如果你有很多并且它们已编号。另外,我建议首先检查完整性,检查读取的列数是否正确。

答案 2 :(得分:-1)

这应该有效:(来自http://www.hotblue.com/article0000.aspx?a=0006

只需将逗号部分替换为:

if ((postdata || !quoted) && (c == ',' || c == '\t'))

使其以制表符分隔。

using System.Data;
using System.IO;
using System.Text.RegularExpressions;

public DataTable ParseCSV(string inputString) {

  DataTable dt=new DataTable();

  // declare the Regular Expression that will match versus the input string
  Regex re=new Regex("((?<field>[^\",\\r\\n]+)|\"(?<field>([^\"]|\"\")+)\")(,|(?<rowbreak>\\r\\n|\\n|$))");

  ArrayList colArray=new ArrayList();
  ArrayList rowArray=new ArrayList();

  int colCount=0;
  int maxColCount=0;
  string rowbreak="";
  string field="";

  MatchCollection mc=re.Matches(inputString);

  foreach(Match m in mc) {

    // retrieve the field and replace two double-quotes with a single double-quote
    field=m.Result("${field}").Replace("\"\"","\"");

    rowbreak=m.Result("${rowbreak}");

    if (field.Length > 0) {
      colArray.Add(field);                  
      colCount++;
    }

    if (rowbreak.Length > 0) {

      // add the column array to the row Array List
      rowArray.Add(colArray.ToArray());

      // create a new Array List to hold the field values
      colArray=new ArrayList(); 

      if (colCount > maxColCount)
        maxColCount=colCount;

      colCount=0;
    }
  }

  if (rowbreak.Length == 0) {
    // this is executed when the last line doesn't
    // end with a line break
    rowArray.Add(colArray.ToArray());
    if (colCount > maxColCount)
      maxColCount=colCount;
  }

  // create the columns for the table
  for(int i=0; i < maxColCount; i++)
  dt.Columns.Add(String.Format("col{0:000}",i));

  // convert the row Array List into an Array object for easier access
  Array ra=rowArray.ToArray();
  for(int i=0; i < ra.Length; i++) {                

    // create a new DataRow
    DataRow dr=dt.NewRow();

    // convert the column Array List into an Array object for easier access
    Array ca=(Array)(ra.GetValue(i));               

    // add each field into the new DataRow
    for(int j=0; j < ca.Length; j++)
      dr[j]=ca.GetValue(j);

    // add the new DataRow to the DataTable
    dt.Rows.Add(dr);
  }

  // in case no data was parsed, create a single column
  if (dt.Columns.Count == 0)
    dt.Columns.Add("NoData");

  return dt;
}

现在我们有一个用于将字符串转换为DataTable的解析器,我们现在需要的是一个从CSV文件中读取内容并将其传递给ParseCSV函数的函数:

public DataTable ParseCSVFile(string path) {

  string inputString="";

  // check that the file exists before opening it
  if (File.Exists(path)) {

    StreamReader sr = new StreamReader(path);
    inputString = sr.ReadToEnd();
    sr.Close();

  }

  return ParseCSV(inputString);
}

现在,您可以使用CSV文件中的数据轻松填充DataGrid:

protected System.Web.UI.WebControls.DataGrid DataGrid1;

private void Page_Load(object sender, System.EventArgs e) {

  // call the parser
  DataTable dt=ParseCSVFile(Server.MapPath("./demo.csv"));          

  // bind the resulting DataTable to a DataGrid Web Control
  DataGrid1.DataSource=dt;
  DataGrid1.DataBind();
}