如何将字符串集合作为TextReader传递?

时间:2013-03-31 06:49:17

标签: c# csv stream

我正在使用CSVHelper库,它只需三行代码即可从CSV文件中提取对象列表:

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并在提取对象之前检查每一行,但我觉得有些笨拙。

3 个答案:

答案 0 :(得分:5)

StringReader类提供了一个包装String的TextReader。您可以简单地连接这些行并将它们包装在StringReader中:

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

答案 1 :(得分:0)

一种更简单的方法是使用CsvHelper跳过这些行。

// Skip rows.
csvReader.Configuration.IgnoreBlankLines = false;
csvReader.Configuration.IgnoreQuotes = true;
for (var i = 0; i < 10; i++)
{
    csvReader.Read();
}
csvReader.Configuration.IgnoreBlankLines = false;
csvReader.Configuration.IgnoreQuotes = false;

// Carry on as normal.
var myData = csvReader.GetRecords<MyCustomType>;
如果前10行中的任何一行为空,则

IgnoreBlankLines将关闭。 IgnoreQuotes已关闭,因此如果这些行包含BadDataException,则不会得到任何"。您可以再次将其重新打开以恢复正常功能。

如果您不知道行数并且需要基于行数据进行测试,则可以仅测试csvReader.Context.Record并查看是否需要停止。在这种情况下,您可能需要先手动调用csvReader.ReadHeader(),然后再调用csvReader.GetRecords<MyCustomType>()

答案 2 :(得分:-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);         
}