Получение длины записей в CsvHelper - PullRequest
0 голосов
/ 25 октября 2018

Я использую библиотеку CsvHelper в C# для чтения файла CSV, например:

var dataCsvFileReader = File.OpenText(inputFile);
var dataCsvReader = new CsvReader(dataCsvFileReader);
var dataRecords = dataCsvReader.GetRecords<dynamic>();

foreach(dynamic record in dataRecords){
    for(int i = 0; i < ???; i++){ //How many columns are there in the record???
        Console.WriteLine($"Record {i} value is: {record[i]}");
    }
}

Как вы можете видеть из кода, моя проблема в том, что я неНе знаю, сколько столбцов в записи.Поскольку я не знаю структуру данных до их синтаксического анализа (файлы CSV, которые я имею в качестве входных данных, всегда различны), как я могу узнать, сколько существует столбцов?Я пытался запросить dataCsvReader.Context.ColumnCount, но это всегда возвращает 0.

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Вы можете конвертировать каждую запись в List

using (TextReader dataCsvFileReader = File.OpenText(inputFile))
{
    using (CsvReader dataCsvReader = new CsvReader(dataCsvFileReader))
    {
        while (dataCsvReader.Read())
        {
            var dataRecord = Enumerable.ToList(dataCsvReader.GetRecord<dynamic>());
        }
    }
}
0 голосов
/ 25 октября 2018

Здесь решение перечисляет, отслеживает и показывает значение вашей динамики CSV.
Чтобы прочитать и найти столбец, вам нужно немного информации: Разделитель, кодировка, если файл имеет заголовок.Без этого невозможно достичь этого.В следующем примере я использую значение по умолчанию для заголовка и кодировки.

Здесь идея заключается в обработке конвертирования CSV в List<Dictionary<string, object>>using нет возможности освободить StreamReader как можно скорее.

List<IDictionary<string, object>> dataRecords  ;

using (TextReader reader = new StreamReader(path))
using (var csvReader = new CsvReader(reader))
{
    csvReader.Configuration.Delimiter = ";";
    dataRecords = csvReader.GetRecords<dynamic>()
                           .Select(x =>  (IDictionary<string, object>)x) 
                           .ToList();
}

foreach (var record in dataRecords)
{
    // Print number of columns, and columns collection.
    Console.WriteLine($"-> {record.Count} Columns {{{string.Join(", ", record.Keys)}}}");
    foreach (var property in record.Keys)
    {
        Console.WriteLine(String.Format("\t{0} : {1}", property, record[property]));
    }
}

Чтобы избежать возможных проблем с производительностью, вы можете использовать словарь, например:

.Select(x => new Dictionary<string, object>((IDictionary<string, object>)x))

Результат:

-> 43 Columns {Method, Job, AnalyzeLaunchVariance,...}  
    Method : DiffOriginalNoAny  
    Job : Default  
    AnalyzeLaunchVariance : False  

-> 43 Columns {Method, Job, AnalyzeLaunchVariance,...}  
   Method : DiffOriginal  
   Job : Default  
   AnalyzeLaunchVariance : False  
0 голосов
/ 25 октября 2018

Одна вещь, которую вы должны помнить, это читать csv перед тем, как получить к нему доступ:

var dataCsvFileReader = File.OpenText(inputFile);
var dataCsvReader = new CsvReader(dataCsvFileReader);
dataCsvReader.Read();
var dataRecords = dataCsvReader.GetRecords<dynamic>();

Я бы порекомендовал using предложение здесь:

var dataCsvFileReader = File.OpenText(inputFile);
using(CsvReader dataCsvReader = new CsvReader(dataCsvFileReader))
{
    //read before accessing csv file
    dataCsvReader.Read();
    //count for columns
    var count = dataCsvReader.Context.ColumnCount;
    var dataRecords = dataCsvReader.GetRecords<dynamic>();
}
...