FileHelpers - Multi Record Processing

  • Contact / Feedback
  • Introduction
  • Download
  • Quick Start
  • Must Read
  • Examples
    • QuickStart
      • Read Delimited File
      • Write Delimited File
      • Read Fixed File
      • Write Fixed File
      • Read or Write Record by Record
      • Autoproperties
    • Missing Values
      • Handle Missing Values with Nullable
      • Handle Missing Values With FieldNullValue
    • Attributes
      • FieldTrim
      • FieldOrder
      • FixedLengthRecord FixedMode.AllowLessChars
    • Converters
      • Enum Converter
      • Custom Converter
    • Events And Notification
      • INotifyRead Interface
      • INotifyWrite Interface
      • Before/After Read Event Handling
      • Before/After Write Event Handling
    • ErrorHandling
      • ErrorMode.ThrowException
      • ErrorMode.IgnoreAndContinue
      • ErrorMode SaveAndContinue
    • Advanced
      • Dynamic Engine Options
      • Multiple Delimiters
      • Multi Record Processing
      • Smart Format Detector
    • Sorting
      • Sort Big File with Record Class
      • Sort Big File without Record Class 1
      • Sort Big File without Record Class 2
    • MasterDetail
      • Master Detail Custom Selector
      • Master Detail Common Selector
  • Credits
  • Invite us a beer
  • Contribute
  • Source Code
  • Api Docs (Sandcastle)
  1. Examples
  2. Advanced
  3. Multi Record Processing
Previous: Multiple Delimiters
Next: Smart Format Detector
Click button to edit
Advanced: Multi Record Processing
Read or write a file with many different layouts

The idea of this engine is to parse files with different record types (this engine doesn't use any hierarchical structure like the master-details, all the records are in linear relation for it).

With the MultiRecordEngine you can parse also mixed delimited and fixed length records.

For example, you can parse this strange file:

Input.txt
10248|VINET|5|04071996|01081996|16071996|3|32.38  
10249|TOMSP|6|05071996|16081996|10071996|1|11.61
ALFKI;Alfreds Futterkiste;Maria Anders;Sales Representative;Obere Str. 57;Berlin;Germany
ANATR;Ana Trujillo Emparedados y helados;Ana Trujillo;Owner;Avda. de la Constitución 2222;México D.F.;Mexico
10250|HANAR|4|08071996|05081996|12071996|2|65.83
10111314012345
11101314123456
10251|VICTE|3|08071996|05081996|15071996|1|41.34
11121314901234
10101314234567
ANTON;Antonio Moreno Taquería;Antonio Moreno;Owner;Mataderos  2312;México D.F.;Mexico
BERGS;Berglunds snabbköp;Christina Berglund;Order Administrator;Berguvsvägen  8;Luleå;Sweden

This file contains three record types; Customers(begins with letters, | delimited), Orders(begin with numbers, ';' delimited) and the sample type of the first example.

Customer.cs
[DelimitedRecord(";")]
public class Customer
{
    public string CustomerID;
    public string CompanyName;
    public string ContactName;
    public string ContactTitle;
    public string Address;
    public string City;
    public string Country;

    public override string ToString()
    {
        return "Customer: " + CustomerID + " - " + CompanyName + ", " + ContactName;
    }
}
SampleType.cs
[FixedLengthRecord]
public class SampleType
{
    [FieldFixedLength(8)]
    [FieldConverter(ConverterKind.Date, "ddMMyyyy")]
    public DateTime Field1;

    [FieldFixedLength(3)]
    [FieldAlign(AlignMode.Left, ' ')]
    [FieldTrim(TrimMode.Both)]
    public string Field2;

    [FieldFixedLength(3)]
    [FieldAlign(AlignMode.Right, '0')]
    [FieldTrim(TrimMode.Both)]
    public int Field3;

    public override string ToString()
    {
        return "SampleType: " + Field2 + " - " + Field3;
    }
}
Orders.cs
[DelimitedRecord("|")]
public class Orders
{
    public int OrderID;

    public string CustomerID;

    public int EmployeeID;

    public DateTime OrderDate;

    public DateTime RequiredDate;

    [FieldNullValue(typeof(DateTime), "2005-1-1")]
    public DateTime ShippedDate;

    public int ShipVia;

    public decimal Freight;

    public override string ToString()
    {
        return "Orders: " + OrderID + " - " + CustomerID + " - " + Freight;
    }
}

To work with this engine you must create one instance of it in this way:

RunEngine.cs
var engine = new MultiRecordEngine(typeof (Orders),
    typeof (Customer),
    typeof (SampleType));

engine.RecordSelector = new RecordTypeSelector(CustomSelector);

var res = engine.ReadFile("Input.txt");

foreach (var rec in res)
    Console.WriteLine(rec.ToString());

This is the selector that determines the record type based on whatever criteria you write

Selector.cs
private Type CustomSelector(MultiRecordEngine engine, string recordLine)
{
    if (recordLine.Length == 0)
        return null;

    if (Char.IsLetter(recordLine[0]))
        return typeof (Customer);
    else if (recordLine.Length == 14)
        return typeof (SampleType);
    else
        return typeof (Orders);
}
Console
Orders: 10248 - VINET - 32,38
Orders: 10249 - TOMSP - 11,61
Customer: ALFKI - Alfreds Futterkiste, Maria Anders
Customer: ANATR - Ana Trujillo Emparedados y helados, Ana Trujillo
Orders: 10250 - HANAR - 65,83
SampleType: 012 - 345
SampleType: 123 - 456
Orders: 10251 - VICTE - 41,34
SampleType: 901 - 234
SampleType: 234 - 567
Customer: ANTON - Antonio Moreno Taquería, Antonio Moreno
Customer: BERGS - Berglunds snabbköp, Christina Berglund
Copyright © 2020 Devoo - Marcos Meli All rights reserved. Template Design by GeeksLabs