получение неправильного формата столбцов/строк извлечение столбцов и строк из файла CSV (OleDbConnection и доступ к данным))

#c# #csv #datatable #registry #oledbconnection

Вопрос:

У меня проблема с CSV-файлом.

Я пытаюсь получить столбцы и строки из файла CSV, но мой код(ниже) не получает строки и столбцы в правильном формате.

Пример для файла CSV

Код, который я сейчас использую, выглядит так:

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

using (FileStream stream = File.Open(Path.Combine(@"C:UsersmulusDesktop", "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
  • изменено «; Расширенные свойства = «Текст;FMT=С разделителями (;)»»);» для форматирования=с разделителями(;), FMT=Табличный ограничитель и Формат=Табличный ограничитель (он просто игнорирует его)
  • Попытался изменить его в самом реестре, но возникла эта ошибка (Невозможно отредактировать: ошибка при записи новых значений значения)
  • Я также пытался дать мне «Полный контроль», но у меня недостаточно прав для этого

Но я также пытался сделать это с другим кодом, но этот игнорирует символ «;» в столбце B («45;43») и видит его как 2 столбца вместо 1, и в целом форматирование действительно искажено:

 using (StreamReader sr = new StreamReader(strFilePath, Encoding.Default))
{
    string[] headers = sr.ReadToEnd().Split(new string[] { "rn" }, 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,

Комментарии:

1. вы проверили файл, который вы связали в качестве примера ? Это CSV-файл ?

Ответ №1:

Используйте пакет CSVHelper https://joshclose.github.io/CsvHelper/
Как реактивный двигатель, так и ваше собственное домашнее решение не могут превзойти то, что CSVHelper может сделать для вас из коробки.

Использование этого MCVE на основе ваших скриншотов:

 var sb = new StringBuilder();
sb.AppendLine("A;B;C;D;E;");
sb.AppendLine("1;"45;43";"-An-Bn-C";tomato;potato;");
sb.AppendLine("2;"55;34";"-Dn-En-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");
    }
}

 

Я получаю этот вывод:

введите описание изображения здесь

И я использовал этот класс 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;}
    
};
 

Для справки: Реактивный двигатель никогда не прочитает этот пример CSV-файла для вас осмысленным образом. Он не создан для работы с разрывами строк внутри текстовых полей.