我正在使用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并在提取对象之前检查每一行,但我觉得有些笨拙。
答案 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);
}