FluentFiles is a fork of the FlatFile project. It is a library for reading and writing fixed-width and delimited text files.
The following installs the FluentFiles metapackage that pulls in all other packages:
dotnet add package FluentFiles
You should install FluentFiles.Delimited with NuGet:
dotnet add package FluentFiles.Delimited
You should install FluentFiles.Delimited.Attributes with NuGet:
dotnet add package FluentFiles.Delimited.Attributes
You should install FluentFiles.FixedLength with NuGet:
dotnet add packageFluentFiles.FixedLength
You should install FluentFiles.FixedLength.Attributes with NuGet:
dotnet add package FluentFiles.FixedLength.Attributes
You should install FluentFiles.Converters with NuGet:
dotnet add package FluentFiles.ConvertersThese commands will download and install FluentFiles and all required dependencies.
publicsealedclassDelimitedSampleRecordLayout:DelimitedLayout<FixedSampleRecord>{publicDelimitedSampleRecordLayout(){this.WithDelimiter(";").WithQuote("\"").WithMember(x =>x.Id).WithMember(x =>x.Name).WithMember(x =>x.Description, c =>c.WithName("AnotherName"));}}publicsealedclassFixedSampleRecordLayout:FixedLayout<FixedSampleRecord>{publicFixedSampleRecordLayout(){this.WithMember(x =>x.Id, c =>c.WithLength(11)).WithMember(x =>x.Name, c =>c.WithLength(160)).WithMember(x =>x.Description, c =>c.WithLength(6));}}publicclassLayoutFactory{publicIDelimitedLayout<TestObject>GetLayout(){IDelimitedLayout<TestObject>layout=newDelimitedLayout<TestObject>().WithDelimiter(";").WithQuote("\"").WithMember(x =>x.Id).WithMember(x =>x.Description).WithMember(x =>x.NullableInt, c =>c.AllowNull("=Null"));returnlayout;}}publicclassLayoutFactory{publicIFixedLayout<TestObject>GetLayout(){IFixedLayout<TestObject>layout=newFixedLayout<TestObject>().WithMember(x =>x.Id, c =>c.WithLength(5).WithLeftPadding('0')).WithMember(x =>x.Description, c =>c.WithLength(25).WithRightPadding(' ')).WithMember(x =>x.NullableInt, c =>c.WithLength(5).AllowNull("=Null").WithLeftPadding('0'));returnlayout;}// You can also register a StringNormalizer function to convert input into the FixedLengthLineBuilder// to a string compatible with the specifications for your target file. //// Note that the StringNormalizer function is only used when writing files, not when reading files.//// Example:publicIFixedLayout<TestObject>GetLayout(){IFixedLayout<TestObject>layout=newFixedLayout<TestObject>().WithMember(x =>x.Description, c =>c.WithLength(25).WithRightPadding(' ').WithStringNormalizer(input =>{// the normalization to FormD splits accented letters in accents+letters,// the rest aftet that removes those accents (and other non-spacing characters) from the ouput// So unicode L'été becomes L'etereturnnewstring(input.Normalize(System.Text.NormalizationForm.FormD).ToCharArray().Where(ch =>CharUnicodeInfo.GetUnicodeCategory(ch)!=UnicodeCategory.NonSpacingMark).ToArray());}))
return layout;}usingFlatFile.Delimited.Attributes;[DelimitedFile(Delimiter=";",Quotes="\"")]publicclassTestObject{[DelimitedField(1)]publicintId{get;set;}[DelimitedField(2)]publicstringDescription{get;set;}[DelimitedField(3,NullValue="=Null")]publicint?NullableInt{get;set;}}usingFlatFile.FixedLength;usingFlatFile.FixedLength.Attributes;[FixedLengthFile]publicclassTestObject{[FixedLengthField(1,5,PaddingChar='0')]publicintId{get;set;}[FixedLengthField(2,25,PaddingChar=' ',Padding=Padding.Right)]publicstringDescription{get;set;}[FixedLengthField(2,5,PaddingChar='0',NullValue="=Null")]publicint?NullableInt{get;set;}}varlayout=newFixedSampleRecordLayout();varfactory=newFixedLengthFileEngineFactory();using(varstream=newMemoryStream(Encoding.UTF8.GetBytes(FixedFileSample))){varflatFile=factory.GetEngine(layout);varrecords=flatFile.Read<FixedSampleRecord>(stream).ToArray();}varfactory=newFixedLengthFileEngineFactory();using(varstream=newMemoryStream(Encoding.UTF8.GetBytes(FixedFileSample))){varflatFile=factory.GetEngine<FixedSampleRecord>();varrecords=flatFile.Read<FixedSampleRecord>(stream).ToArray();}varfactory=newFixedLengthFileEngineFactory();using(varstream=newMemoryStream(Encoding.UTF8.GetBytes(FixedFileSample))){// If using attribute mapping, pass an array of record types// rather than layout instancesvarlayouts=newILayoutDescriptor<IFixedFieldSettingsContainer>[]{newHeaderRecordLayout(),newDetailRecordLayout(),newTrailerRecordLayout()};varflatFile=factory.GetEngine(layouts,
line =>{// For each line, return the proper record type.// The mapping for this line will be loaded based on that type.// In this simple example, the first character determines the// record type.if(String.IsNullOrEmpty(line)||line.Length<1)returnnull;switch(line[0]){case'H':returntypeof(HeaderRecord);case'D':returntypeof(DetailRecord);case'T':returntypeof(TrailerRecord);}returnnull;});flatFile.Read(stream);varheader=flatFile.GetRecords<HeaderRecord>().FirstOrDefault();varrecords=flatFile.GetRecords<DetailRecord>();vartrailer=flatFile.GetRecords<TrailerRecord>().FirstOrDefault();}varsampleRecords=GetRecords();varlayout=newFixedSampleRecordLayout();varfactory=newFixedLengthFileEngineFactory();using(varstream=newMemoryStream()){varflatFile=factory.GetEngine(layout);flatFile.Write<FixedSampleRecord>(stream,sampleRecords);}varsampleRecords=GetRecords();varfactory=newFixedLengthFileEngineFactory();using(varstream=newMemoryStream()){varflatFile=factory.GetEngine<FixedSampleRecord>();flatFile.Write<FixedSampleRecord>(stream,sampleRecords);}