2013-03-31 4 views
2

Я использую библиотеку CSVHelper, который может извлечь список объектов из CSV файла с помощью всего три строки кода:Как передать коллекцию строк как TextReader?

var streamReader = // Create a reader to your CSV file. 
var csvReader = new CsvReader(streamReader); 
List<MyCustomType> myData = csvReader.GetRecords<MyCustomType>(); 

Однако, файл имеет бессмысленные строки, и мне нужно, чтобы пропустить первые десять строк в файле. Я думал, что неплохо было бы использовать LINQ для обеспечения «чистых» данных, а затем передать эти данные в CsvFReader, например, так:

public TextReader GetTextReader(IEnumerable<string> lines) 
{ 
    // Some magic here. Don't want to return null; 
    return TextReader.Null; 
} 
public IEnumerable<T> ExtractObjectList<T>(string filePath) where T : class 
{ 
    var csvLines = File.ReadLines(filePath) 
         .Skip(10) 
         .Where(l => !l.StartsWith(",,,")); 
    var textReader = GetTextReader(csvLines); 
    var csvReader = new CsvReader(textReader); 
    csvReader.Configuration.ClassMapping<EventMap, Event>(); 
    return csvReader.GetRecords<T>(); 
} 

Но я действительно застрял в толкая «статический» набор строк через поток как TextReaer.

Моей альтернативой является обработка файла CSV по строкам через CsvReader и проверка каждой строки перед извлечением объекта, но я нахожу это несколько неуклюжим.

+0

Я бы, вероятно, пошел со вторым вариантом, тогда вам не нужно хранить весь файл в памяти (например, вы сейчас делаете) – Magnus

+0

Да, подумав об этом, я согласен. Файл предназначен для парковки, тех, кто использует безналичную систему, входы и существует со всей страны и, безусловно, будет довольно большой. Хотя это Невидимый вариант. Второй вариант выше по-прежнему делает все сразу процесс правильной записи. – ProfK

ответ

4

Класс StringReader предоставляет TextReader, который обертывает String. Вы могли бы просто присоединиться к линии и обернуть их в StringReader:

public TextReader GetTextReader(IEnumerable<string> lines) 
{ 
    return new StringReader(string.Join("\r\n", lines)); 
} 
+0

Что я только что узнал. Я все равно хотел бы выполнить всю задачу в одном запросе phat LINQ, как я хочу, но это прекрасно, спасибо. – ProfK

-1

Вы можете попробовать этот путь - преобразовать набор строк в массивы байтов, сцепить их и построить поток его:

private static TextReader GetTextReader(IEnumerable<string> lines) 
{    
    var encoding = System.Text.Encoding.Unicode; 

    var bytesarrays = lines.Select(encoding.GetBytes); 
    var bytes = bytesarrays.SelectMany(i => i).ToArray(); 
    var stream = new MemoryStream(bytes); 
    return new StreamReader(stream, encoding);   
} 
+0

Извините за мою предыдущую ошибку, я не рассматривал кодировку. Это исправлено. – jwaliszko

+1

Зачем беспокоиться о байтах? Просто конкатенируйте струны? – ProfK

Смежные вопросы