从 CSV 文件OleDbConnection 和 DataTable中检索列和行时获取错误的列/行格式

问题描述

我的 CSV 文件有问题。

我试图从 CSV 文件获取列和行,但我的代码(如下)没有以正确的格式获取行和列。

CSV File 的示例

我现在使用的代码如下所示:

DataTable dt = new DataTable();
string FileName = strFilePath;

using (FileStream stream = File.Open(Path.Combine(@"C:\Users\mulus\Desktop","schema.ini"),FileMode.Create,FileAccess.Write,FileShare.None))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        writer.WriteLine(string.Format("[{0}]",FileName));
        writer.WriteLine("Format=Delimited(;)");
        writer.WriteLine("TextDelimiter=\"");
        writer.WriteLine("ColNameHeader=True");
    }
}
            
OleDbConnection conn = new OleDbConnection
       ("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " +
         Path.GetDirectoryName(FileName) +
         "; Extended Properties = \"Text;FMT=Delimited(;)\"");
conn.open();

var abc = Path.GetFileName(FileName);

OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + Path.GetFileName(FileName),conn);
adapter.Fill(dt);

conn.Close();

我尝试了很多东西:

  • 在 FileStream 类上尝试了不同的格式
  • 不使用 FileStream 类
  • 将 "; Extended Properties = "Text;FMT=Delimited(;)"");" 更改为 Format=Delimited(;)、FMT=TabDelimiter 和 Format=TabDelimiter(它只是忽略它)
  • 尝试在注册表中更改它,但出现了 error(无法编辑:写入值的新内容时出错)
  • 我也尝试给我“完全控制”,但我没有足够的权限来执行此操作

但我也尝试用不同的代码来做到这一点,但这个忽略了“;” B 列中的符号(“45;43”)并将其视为 2 列而不是 1 列,总体而言,格式确实很混乱:

using (StreamReader sr = new StreamReader(strFilePath,Encoding.Default))
{
    string[] headers = sr.ReadToEnd().Split(new string[] { "\r\n" },StringSplitOptions.None);
    foreach (string header in headers)
    {
        dt.Columns.Add(header);
    }
    while (!sr.EndOfStream)
    {
        string[] rows = sr.ReadLine().Split(';');
        DaTarow dr = dt.NewRow();
        for (int i = 0; i < headers.Length; i++)
        {
            dr[i] = rows[i];
        }
        dt.Rows.Add(dr);
    }

}

此外,似乎将此代码用于 CSV 文件很容易出错,而且根本不是一个好主意。

如果您对错误有任何想法或其他想法如何做到这一点,我将不胜感激。

系统:Winodws 7、Excel 2010、

解决方法

使用 CsvHelper 包 https://joshclose.github.io/CsvHelper/
JET 引擎和您自己的自制解决方案都无法超越 CsvHelper 为您提供的开箱即用功能。

根据您的屏幕截图使用此 MCVE:

var sb = new StringBuilder();
sb.AppendLine("A;B;C;D;E;");
sb.AppendLine("1;\"45;43\";\"-A\n-B\n-C\";tomato;potato;");
sb.AppendLine("2;\"55;34\";\"-D\n-E\n-F\";carrot;parrot;");

var config = new CsvHelper.Configuration.CsvConfiguration{ Delimiter =";"};
using (var reader = new StringReader(sb.ToString()))
using (var csv = new CsvReader(reader,config))
{
    var cnt =1;
    var records = csv.GetRecords<Row>();
    foreach(var rec in records)
    {     
       cnt++.Dump("record");
       rec.A.Dump("A");
       rec.B.Dump("B");
       rec.C.Dump("C");
       rec.D.Dump("D");
       rec.E.Dump("E");
    }
}

我得到这个输出:

enter image description here

我使用了这个 DTO 类:

class Row
{
   public string A {get;set;}
   public string B {get;set;}
   public string C {get;set;}
   public string D {get;set;}
   public string E {get;set;}
    
};

声明:JET 引擎永远不会以有意义的方式为您读取该示例 CSV 文件。它不是为了处理文本字段内的换行符而构建的。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...