1

Is it possible to parse/read a fixed position layout flat file when the positions are only known at run time? I see there is a question on SO that relates to something similar using 'Runtime Records' but this relates reading a delimited file - Dynamically create a Fixed Length text file with FileHelpers

My intention is to parse fixed length flat files with different fixed length formats to a common format, and the fixed length format is loaded at runtime. FileHelpers tends to use attributes to define the position and length of the field, which is defined up front but I would like to specify this at runtime.

thanks.

Community
  • 1
  • 1
user3086298
  • 290
  • 1
  • 4
  • 14
  • digging as bit deeper it Im thinking now that it might be possible by using reflection to set attribute properties, I would just like to know if there is a cleaner solution... thanks http://stackoverflow.com/questions/18201971/how-do-i-get-the-custom-attribute-value-of-a-field – user3086298 Sep 11 '15 at 14:26
  • 1
    Can I clarify what you intend to do here. You intend to have the same character width, ie 80 characters wide, but the internal size of each column and the number of columns can change? However, once the data is loaded in Class1, you want to transfer the data to Class2? where the layout may have shrunk a column or added a new one? Can you provide a quick example project of what you want (albeit without the RuntimeHelpers magic) – netniV Sep 11 '15 at 16:54
  • different files might have different positions for a field, so say CustomerName might be start 10 end 20 in one file but in another file it might be start 50 end 90 – user3086298 Sep 15 '15 at 19:02

1 Answers1

2

This is what i did. Hope it may help you.

  1. Created DB table and stored the different Fixed File layout formats (like Field Name size, Data Type and Length of the field etc...)
  2. In UI first user selects the Fixed File Layout and then selects the Fixed File to import.
  3. Based on selected Layout i create Fixed length Type class at run time using the below code.



private void ImportFiles()
{
    DataTable dt = GetFixedFileSpecsFromDB(layoutName); //Get the specs
    //Create Dynamic class based on Specs above
    FixedLengthClassBuilder cb = GetSpecClass(dt);
    //Create FileHelpers engine instance
    FileHelperEngine engine = new FileHelperEngine(cb.CreateRecordClass());
    //Read file data into Data table
    DataTable dtImportData = engine.ReadFileAsDT(ImportFilePath);
}

//Method to create the Fixed lentgh dynamic class
 public static FixedLengthClassBuilder GetSpecClass(DataTable dt)
    {

        string className = "ImportSpecifications";
        FixedLengthClassBuilder cb = new FixedLengthClassBuilder(className);
        //Loop thru each field and prepare the class
        foreach (DataRow dr in dt.Rows)
        {
            int fieldLength = Convert.ToInt32(dr.Field<decimal>("FieldLength"));
            switch (dr["FieldDataType"].ToString())
            {
                case "String":
                    cb.AddField(dr.Field<string>("FieldName"), fieldLength, typeof(string));
                    cb.LastField.FieldNullValue = string.Empty;
                    cb.LastField.TrimMode = FileHelpers.TrimMode.Both;
                    break;
                case "Date":
                    cb.AddField(dr.Field<string>("FieldName"), fieldLength, typeof(DateTime));
                    cb.LastField.FieldNullValue = string.Empty;
                    break;
                case "Integer":
                    cb.AddField(dr.Field<string>("FieldName"), fieldLength, typeof(int?));
                    //cb.LastField.FieldNullValue = 0;
                    break;
                case "Long Integer":
                    cb.AddField(dr.Field<string>("FieldName"), fieldLength, typeof(long));
                    cb.LastField.FieldNullValue = 0;
                    break;
                case "Decimal":
                    cb.AddField(dr.Field<string>("FieldName"), fieldLength, typeof(decimal?));
                    //cb.LastField.FieldNullValue = 0;
                    break;
                default:
                    break;
            }
        }
        return cb;
    }
Manoj
  • 60
  • 1
  • 7
  • thanks thats kind of what I thought, I was thinking custom attributes which worked for me but at least this is a different angle to try... – user3086298 Sep 22 '15 at 15:11