简体   繁体   English

filehelpers - 解析变量行长度

[英]filehelpers - Parsing variable line length

I have to parse (C#) a .CSV file, with a variable "width" and 2 lines of header information (the fist one being name and the second one being the unit). 我必须解析(C#)一个.CSV文件,其中包含一个变量“width”和两行标题信息(第一个是名称,第二个是单位)。

The data looks like: 数据看起来像:

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

With N being the "width" of the table (value can be up to 128 and larger). N是表的“宽度”(值可以高达128或更大)。 I'm planning to use Filehelpers . 我打算使用Filehelpers

I thought of using [FieldOptional()] - but that gets very unhandy, especially when the "width" is variable... 我想过使用[FieldOptional()] - 但这非常不方便,特别是当“width”变量时......

My current attempt looks like 我目前的尝试看起来像

[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
}

Any help on "how to solve the variable width"-Problem in a more elegant manner is appreciated - Thank you very much in advance! 任何有关“如何解决可变宽度”的问题 - 以更优雅的方式提出的问题表示赞赏 - 非常感谢您提前!

Ben

If you are planning to convert the file into DataTable, there is a better option 如果您计划将文件转换为DataTable,则有更好的选择

Please use CsvEngine of FileHelpers library. 请使用FileHelpers库的CsvEngine。 See the code snippet below: 请参阅下面的代码段:

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

}

Here the sample file can be csv file or text file contains the header of the csv file you want to process. 这里的示例文件可以是csv文件,也可以是包含要处理的csv文件头的文本文件。 The columns of the DataTable will be named according to the header of the sample file DataTable的列将根据示例文件的标题命名

Cheers 干杯

You can use optional array field. 您可以使用可选的数组字段。 I think you need to be using FileHelpers 2.9.9. 我认为你需要使用FileHelpers 2.9.9。

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

    [FieldNullValue(0.0)]
    [FieldOptional, FieldArrayLength(0, 100)]
    public Double[] ManyFields;
}

Here's a working example. 这是一个有效的例子。

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]);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM