C# filehelpers-解析可变行长度

C# filehelpers-解析可变行长度,c#,csv,width,line,filehelpers,C#,Csv,Width,Line,Filehelpers,我必须解析(C#)一个.CSV文件,该文件具有可变的“宽度”和两行标题信息(第一行是名称,第二行是单位) 数据如下所示: 示例1.CSV: "timestamp","NAME_1","NAME_2","NAME_3","NAME_4" "ms","unit_1","unit_2","unit_3","unit_4" 0.01,1.23,4.56,7.89,0.12 0.02,1.23,4.66,7.89,0.11 0.03,1.23,4.76,7.89,0.11 0.04,56.23,4.86,

我必须解析(C#)一个
.CSV
文件,该文件具有可变的“宽度”和两行标题信息(第一行是名称,第二行是单位)

数据如下所示:

示例1.CSV:

"timestamp","NAME_1","NAME_2","NAME_3","NAME_4"
"ms","unit_1","unit_2","unit_3","unit_4"
0.01,1.23,4.56,7.89,0.12
0.02,1.23,4.66,7.89,0.11
0.03,1.23,4.76,7.89,0.11
0.04,56.23,4.86,7.89,0.12
示例2.CSV:

"timestamp","NAME_1","NAME_2","NAME_3","NAME_4","NAME_5",...,"NAME_N"
"ms","unit_1","unit_2","unit_3","unit_4","unit_5",...,"unit_N"
0.01,1.23,4.56,7.89,0.12,0.13,...,0.27
0.02,1.23,4.66,7.89,0.12,0.13,...,0.22
0.03,1.23,4.76,7.89,0.11,0.13,...,0.24
0.04,56.23,4.86,7.89,0.12,0.13,...,0.29
N是表格的“宽度”(值可以高达128或更大)。我打算用它

我曾想过使用
[FieldOptional()]
——但这很不方便,尤其是当“宽度”可变时

我目前的尝试看起来像

[IgnoreFirst(2)]
[DelimitedRecord(",")]
public sealed class LogData
{

    public Double ts;

    public Double Field1;

    [FieldNullValue(0.0)]
    [FieldOptional()]
    public Double Field2;

    [FieldNullValue(0.0)]
    [FieldOptional()]
    public Double Field3;

    // and so on
}
任何关于“如何解决可变宽度”的帮助-以更优雅的方式解决问题-都将不胜感激-非常感谢


Ben

如果您计划将文件转换为DataTable,那么有一个更好的选择

请使用FileHelpers库的CsvEngine。请参见下面的代码片段:

using (MemoryStream stream = new MemoryStream(_fileContent)) //file content can be file as byte array
            {
                TextReader reader = new StreamReader(stream);
string path = "C:\\Sample.csv";
                CsvEngine csvEngine = new CsvEngine("Model", ',', path);
                var dataTable = csvEngine.ReadStreamAsDT(reader);
//Do whatever with dataTable

}
这里的示例文件可以是csv文件,也可以是包含要处理的csv文件头的文本文件。DataTable的列将根据示例文件的标题命名


干杯

您可以使用可选的数组字段。我认为您需要使用FileHelpers 2.9.9

[IgnoreFirst(2)]
[DelimitedRecord(",")]
public class LogData
{
    public Double TimeStamp;

    [FieldNullValue(0.0)]
    [FieldOptional, FieldArrayLength(0, 100)]
    public Double[] ManyFields;
}
这里有一个有效的例子

class Program
{
    static String content = 
         @"""timestamp"",""NAME_1"",""NAME_2"",""NAME_3"",""NAME_4""
         ""ms"",""unit_1"",""unit_2"",""unit_3"",""unit_4""
         0.01,1.23,4.56,7.89,0.12
         0.02,1.23,4.66,7.89,0.11
         0.03,1.23,4.76,7.89,0.11
         0.04,56.23,4.86,7.89,0.12";

    private static void Main()
    {
        var engine = new FileHelperEngine<LogData>();
        var records = engine.ReadString(content);
        Assert.AreEqual(0.01, records[0].TimeStamp);
        Assert.AreEqual(1.23, records[0].ManyFields[0]);
        Assert.AreEqual(4.56, records[0].ManyFields[1]);
        Assert.AreEqual(7.89, records[0].ManyFields[2]);
        Assert.AreEqual(0.12, records[0].ManyFields[3]);
    }
}
类程序
{
静态字符串内容=
@“时间戳”、“名称1”、“名称2”、“名称3”、“名称4”
“ms”、“1号机组”、“2号机组”、“3号机组”、“4号机组”
0.01,1.23,4.56,7.89,0.12
0.02,1.23,4.66,7.89,0.11
0.03,1.23,4.76,7.89,0.11
0.04,56.23,4.86,7.89,0.12";
私有静态void Main()
{
var engine=new FileHelperEngine();
var记录=engine.ReadString(内容);
Assert.AreEqual(0.01,记录[0]。时间戳);
Assert.AreEqual(1.23,记录[0]。多个字段[0]);
Assert.AreEqual(4.56,记录[0]。多个字段[1]);
Assert.AreEqual(7.89,记录[0]。多个字段[2]);
Assert.AreEqual(0.12,记录[0]。多个字段[3]);
}
}

阅读CSV文件后,您计划如何使用模型?模型用于打印和过滤数据。我正在处理来自
LogData[]res=engine.ReadFile(@.\\..\\testdata.csv)的数组结果或者我正在将其转换为数据表-我计划让性能测试来决定。Boombastico!甚至第一行也会自动添加为
dataTable.Columns[i].ColumnName
。你知道我如何在
数据表中存储特定于列的单位信息吗?可能滥用
ColumnName
以及自定义转换器和自定义分隔符“| | | |”?@Ben如果值的数量与列的数量相同,则可以将CSV第二行中的单位信息作为数据表中的第二行。如果在任何自定义格式中都需要相同的值,则需要使用一些调整。遗憾的是,这不是选项,因为我想在以后将[1]值转换为
双精度
数据表
(用于值打印和处理所需)。[1]