filehelpers - 解析可变行长

Posted

技术标签:

【中文标题】filehelpers - 解析可变行长【英文标题】:filehelpers - Parsing variable line length 【发布时间】:2014-05-31 07:05:56 【问题描述】:

我必须解析 (C#) 一个 .CSV 文件,其中包含变量“宽度”和 2 行标题信息(第一行是名称,第二行是单位)。

数据如下:

Example1.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

Example2.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 或更大)。我打算用Filehelpers。

我曾想过使用[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

任何有关“如何解决可变宽度”的帮助 - 以更优雅的方式解决问题 - 非常感谢您!

【问题讨论】:

阅读完 CSV 文件后,您打算如何使用该模型? 模型用于绘制和过滤数据。要么我正在使用来自 LogData[] res = engine.ReadFile(@"..\\..\\testdata.csv"); 的 Array-Result,要么我正在将其转换为 DataTable - 我打算让性能测试来决定。 【参考方案1】:

如果您打算将文件转换为 DataTable,有更好的选择

请使用 FileHelpers 库的 CsvEngine。见下面的代码sn-p:

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的列将根据示例文件的标题命名

干杯

【讨论】:

轰炸机!甚至第一行也会自动添加为dataTable.Columns[i].ColumnName。知道如何将列特定的单元信息也存储在DataTable 中(.CSV 中的第二行)?也许滥用ColumnName 以及自定义转换器和自定义分隔符“|||”? @Ben 如果值的个数与列数相同,则可以将CSV第二行中的单位信息作为DataTable中的第二行。如果您需要任何自定义格式的相同内容,则需要进行一些调整。 遗憾的是,这是没有选择的,因为我想在之后将 [1] 值转换为 Double DataTable (需要处理值的绘图和处理)。 [1]***.com/questions/9028029/…【参考方案2】:

您可以使用可选的数组字段。我认为您需要使用 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]);
    

【讨论】:

以上是关于filehelpers - 解析可变行长的主要内容,如果未能解决你的问题,请参考以下文章

如何在列表视图中为带有自动换行的可变多行长文本自动调整项目高度?

使用 C# 将 FileHelpers 数据排序到 SQl 服务器中的不同列中

无法解析命令行长选项

解析 Hello World 警告 - 正在主线程上执行长时间运行的操作

使用 FileHelpers 处理引号

忽略FileHelpers中的属性