我正在使用csvHelper来读取txt文件,其中列的名称可以是“column1”。
当然我不想在我的ColumnAttribute
中放置这么难看的字符串[ColumnInfo(typeof(string), "column1")
public string Column1{get;set;}
这就是
之前的原因var reader = new CsvReader(path);
var result = reader.GetRecords<MyObject>();
我想在读取之前预先处理文件的列名。
所以,我做了预处理器
public void TrimmColumns(ref StreamReader reader)
{
var columns = reader.ReadLine();
if (columns != null)
{
columns = string.Join(";", columns.Split(';').Select(str => str.Trim()).ToArray());
var res = columns + reader.ReadToEnd();
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream);
streamWriter.Write(res);
streamWriter.Flush();
stream.Position = 0;
reader = new StreamReader(stream);
}
else
{
throw new ArgumentException("Host file is empty");
}
}
现在我卡住了。我可以从字符串创建流阅读器并返回它但对我来说它看起来不是最好的决定。任何有实际经验的人都可以解释如何使它不仅能够工作而且还能满足正常的编码风格吗?
[更新]这就是我现在正在做的事情,但它看起来并不好看...... [更新2]我刚才意识到它也很糟糕,因为我正在关闭一个流并在此功能中创建其他流。
答案 0 :(得分:0)
好吧,我想出了这个决定,但如果有人请更好,请分享,因为改善非常重要!
using System;
using System.IO;
using System.Linq;
using OtexReportingRef.OtexReader.Interfaces;
public class CsvFileColumnTrimmer:ICsvFileColumnTrimmer
{
public void TrimmColumns(ref StreamReader reader)
{
var columns = reader.ReadLine();
if (columns != null)
{
columns = string.Join(";", columns.Split(';').Select(str => str.Trim()).ToArray());
var res = columns + reader.ReadToEnd();
var stream = WriteStringToStream(res);
reader = new StreamReader(stream);
}
else
{
throw new ArgumentException("Host file is empty");
}
}
public StreamReader TrimmColumns(StreamReader reader)
{
using (reader)
{
var columns = reader.ReadLine();
if (columns != null)
{
columns = string.Join(";", columns.Split(';').Select(str => str.Trim()).ToArray());
var res = columns + reader.ReadToEnd();
var stream = WriteStringToStream(res);
return new StreamReader(stream);
}
else
{
throw new ArgumentException("Host file is empty");
}
}
}
private static MemoryStream WriteStringToStream(string res)
{
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream);
streamWriter.Write(res);
streamWriter.Flush();
stream.Position = 0;
return stream;
}
}
测试是:
using System.IO;
using NUnit.Framework;
using OtexReportingRef.OtexReader.Implementation;
[TestFixture]
public class CsvFileColumnTrimmerTest
{
private const string Columns =
"col1;col2 ;col3 ;";
[Test]
public void TrimColumns_Test()
{
var stream = WriteStringToStream(Columns);
var streamReader = new StreamReader(stream);
var trimmer = new CsvFileColumnTrimmer();
trimmer.TrimmColumns(ref streamReader);
var res = streamReader.ReadLine();
Assert.AreEqual("col1;col2;col3;",res);
}
[Test]
public void TrimColumns_WithUsing_Test()
{
var stream = WriteStringToStream(Columns);
using (var streamReader = new StreamReader(stream))
{
var trimmer = new CsvFileColumnTrimmer();
using (var reader = trimmer.TrimmColumns(streamReader))
{
var res = reader.ReadLine();
Assert.AreEqual("col1;col2;col3;", res);
}
}
}
[Test]
public void TrimColumns_WithTryCatch_Test()
{
var stream = WriteStringToStream(Columns);
var streamReader = new StreamReader(stream);
try
{
var trimmer = new CsvFileColumnTrimmer();
trimmer.TrimmColumns(ref streamReader);
var res = streamReader.ReadLine();
Assert.AreEqual("col1;col2;col3;", res);
}
finally
{
streamReader.Dispose();
}
}
private static MemoryStream WriteStringToStream(string res)
{
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream);
streamWriter.Write(res);
streamWriter.Flush();
stream.Position = 0;
return stream;
}
}