Прочитайте все значения из CSV в список с помощью CsvHelper

поэтому я читал, что я не должен писать свой собственный CSV-ридер/писатель, поэтому я пытался использовать библиотеку CsvHelper, установленную через nuget. Файл CSV-это серый масштаб изображения, количество строк по высоте изображения и количество столбцов в ширину. Я хотел бы прочитать значения по строкам в один List<string> или List<byte>.

код у меня есть до сих пор:

using CsvHelper;

public static List<string> ReadInCSV(string absolutePath)
{
    IEnumerable<string> allValues;

    using (TextReader fileReader = File.OpenText(absolutePath))
    {
        var csv = new CsvReader(fileReader);
        csv.Configuration.HasHeaderRecord = false;
        allValues = csv.GetRecords<string>
    }

    return allValues.ToList<string>();
}

но allValues.ToList<string>() бросает:

CsvConfigurationException было обработано пользовательским кодом

исключение типа ' CsvHelper.Конфигурация.CsvConfigurationException ' произошло в CsvHelper.DLL но не был обработан в пользовательском коде

дополнительная информация: типы, наследующие IEnumerable, не могут быть автоматически сопоставлены. Вы случайно вызвали GetRecord или WriteRecord, который действует на одной записи вместо вызова GetRecords или WriteRecords, который действует в списке записи?

GetRecords вероятно, ожидает мой собственный класс, но я просто хочу, чтобы значения были каким-то примитивным типом или строкой. Кроме того, я подозреваю, что вся строка преобразуется в одну строку, а не каждое значение в отдельную строку.

4 ответов


согласно сообщению @Marc L вы можете попробовать следующее:

public static List<string> ReadInCSV(string absolutePath) {
    List<string> result = new List<string>();
    string value;
    using (TextReader fileReader = File.OpenText(absolutePath)) {
        var csv = new CsvReader(fileReader);
        csv.Configuration.HasHeaderRecord = false;
        while (csv.Read()) {
           for(int i=0; csv.TryGetField<string>(i, out value); i++) {
                result.Add(value);
            }
        }
    }
    return result;
}

Если все, что вам нужно, это строковые значения для каждой строки в массиве, вы можете использовать парсер напрямую.

var parser = new CsvParser( textReader );
while( true )
{
    string[] row = parser.Read();
    if( row == null )
    {
        break;
    }
}

http://joshclose.github.io/CsvHelper/#reading-parsing

обновление

версия 3 поддерживает чтение и запись свойств IEnumerable.


вы находитесь рядом. Дело не в том, что он пытается преобразовать row в строку. CsvHelper пытается сопоставить каждое поле в строке со свойствами данного типа, используя имена, заданные в строке заголовка. Кроме того, он не понимает, как это сделать с IEnumerable типы (которые string implements), поэтому он просто бросает, когда автоматическое сопоставление доходит до этой точки при тестировании типа.


Это очень много осложнений для того, что вы делаете. Если ваш файл формат достаточно прост,каким кажется ваш-хорошо известный формат поля, ни экранированные, ни цитируемые разделители-я не вижу причин, почему вам нужно брать на себя накладные расходы по импорту библиотеки. Вы должны быть в состоянии перечислить значения с System.IO.File.ReadLines() и String.Split().

//pseudo-code...you don't need CsvHelper for this
IEnumerable<string> GetFields(string filepath)
{
  foreach(string row in File.ReadLines(filepath))
  {
    foreach(string field in row.Split(',')) yield return field;
  }
}

пожалуйста, попробуйте это. Это сработало для меня.

TextReader reader = File.OpenText(filePath);
            CsvReader csvFile = new CsvReader(reader);
            csvFile.Configuration.HasHeaderRecord = true;
            csvFile.Read();
            var records = csvFile.GetRecords<Server>().ToList();

Server-это класс сущностей. Вот как я создавал.

 public class Server
    {
        private string details_Table0_ProductName;
        public string Details_Table0_ProductName
        {
            get
            {
                return details_Table0_ProductName;
            }
            set
            {
                this.details_Table0_ProductName = value;
            }
        }

        private string details_Table0_Version;
        public string Details_Table0_Version
        {
            get
            {
                return details_Table0_Version;
            }
            set
            {
                this.details_Table0_Version = value;
            }
        }       
    }