#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-файла для вас осмысленным образом. Он не создан для работы с разрывами строк внутри текстовых полей.