Reputation: 2051
I've got an application on my hands that uses the FileHelpers library to process csv files.
In the past, the input csv files always had the same structure, 5 comma-separated fields for a record, then a new line to delimit records.
Recently, however, I started receiving csv files that have more than five records per line, and, apparently, the class that is currently used for csv parsing isn't applicable for these lines. The thing is, I still only need the first five fields, which are still supplied in he same order.
Is there any way to read the first five fields with FileHelpers, and ignore any other data until a newline?
The class currently used for parsing:
[IgnoreEmptyLines()]
[DelimitedRecord(";")]
public sealed class SemicolonsRow
{
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String LastName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String Name;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String MidName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String BirthDate;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String BirthPlace;
}
Upvotes: 3
Views: 2936
Reputation: 51
Using FileHelper you can add this variable as your last one:
public string[] FunkyNewField;
If you have FieldOrder defined then add it like this:
[FieldOrder(n)]
public string[] FunkyNewField;
where n = number after your last specified order number.
This will contain all the extra columns in your file that you didn't want to use.
Upvotes: 5
Reputation: 2046
The fact that the number of columns is causing a problem would suggest that your design is wrong.
I recently used 'A Fast CSV Reader' to do some CSV parsing and it works absolutely brilliantly. You can index the columns in a simple for
loop, so if you only want that first 5 columns, you can do something like this:
CsvReader csv = new CsvReader(new StreamReader(fileName), true);
// Iterating LINES
while (csv.ReadNextRecord())
{
// Iterating COLUMNS on current line
for (int i = 0; i < 5; i++)
{
string value = csv[i];
// do stuff with value
}
}
Upvotes: 2
Reputation: 3506
A simple solution can be to add some private dummy fields (as optionals) that will get the values
[IgnoreEmptyLines()]
[DelimitedRecord(";")]
public sealed class SemicolonsRow
{
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String LastName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String Name;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String MidName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String BirthDate;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
private String DummyField1;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
private String DummyField2;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
private String DummyField3;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
private String DummyField4;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
private String DummyField5;
}
Upvotes: 2