Examples
The examples directory contains runnable console applications that demonstrate key features of Wolfgang.Etl.FixedWidth. Each example is a standalone project you can build and run with dotnet run.
BasicExtraction
Demonstrates the simplest extraction workflow: defining a record class with [FixedWidthField] attributes, reading fixed-width text from a StringReader, and iterating records with await foreach.
BasicLoading
Demonstrates the simplest loading workflow: writing strongly typed records to fixed-width text output using a StringWriter, including padding, alignment, and pad character behavior.
CompressedStreams
Demonstrates loading to and extracting from compressed streams. Because the Stream-based constructors accept any Stream, GZip and Brotli compression work out of the box — you simply wrap the underlying stream in a GZipStream or BrotliStream. Highlights the disposal ordering required to flush the compressor before the compressed bytes are read back.
RoundTrip
Shows a full round-trip pipeline: extracting records from fixed-width text, then loading them back out to produce identical output. Validates that extraction and loading are symmetric.
CustomParsersConverters
Demonstrates how to plug in custom ValueParser delegates for extraction and custom ValueConverter delegates for loading, enabling non-standard type conversions and formatting.
ProgressReporting
Shows how to use timer-based progress reporting to receive periodic FixedWidthReport snapshots during long-running extraction or loading operations.
ErrorHandling
Demonstrates BlankLineHandling and MalformedLineHandling modes, showing how to skip, error on, or pass through problematic lines during extraction.
FieldDelimiter
Shows how to configure inter-field delimiters (e.g., |) between columns in the fixed-width output, and how the extractor handles delimited input.
SkipAndMax
Demonstrates SkipItemCount and MaximumItemCount for pagination — skipping the first N records and capping the total number of records extracted or loaded.
HeadersAndSeparators
Shows how to enable header row output and separator lines when loading, including custom header text via the Header property on [FixedWidthField].
PipelineExtensions
Composes an extract → transform → load flow as a single EtlPipeline fluent chain: EtlPipeline.Create().FixedWidthExtractor<T>(…) source factories and FixedWidthLoader<T>(…) sink terminators, with inline Through transform stages and 1:1 fluent configuration. Also shows the resource-ownership contract — path factories own and dispose the files they open, while caller-supplied readers/writers are left open. Requires Wolfgang.Etl.Abstractions 0.16.0.
Metrics
Subscribes to the Wolfgang.Etl.FixedWidth meter with a MeterListener and prints the counters and duration histogram the extractor and loader emit during an extract → load round trip (items.extracted, items.loaded, items.skipped, lines.read, operation.duration, each tagged with etl.operation and etl.record_type). In production you would subscribe with AddMeter("Wolfgang.Etl.FixedWidth") via OpenTelemetry instead.
SchemaBuilder
Defines a fixed-width layout in code with FixedWidthSchemaBuilder<T> for a record type that carries no [FixedWidthField] attributes, then uses it — via the extractor/loader Schema property — to load and re-extract records. Also shows that a code-built schema is fully introspectable (ToDiagram / Fields), exactly like an attribute-resolved one.
DataReader
Exposes a fixed-width source as a forward-only IDataReader via FixedWidthDataReader<T>, with the layout taken from T's [FixedWidthField] attributes. It serves each field value directly from the parsed line — no T is allocated per row — then loads a DataTable through DataTable.Load (no database required). In production the same reader flows straight into SqlBulkCopy.WriteToServerAsync, the zero-per-row-allocation path for bulk-loading a database.
BinaryRecords
Reads and writes fixed-length binary (mainframe / COBOL) records — text plus COMP binary-integer and COMP-3 packed-decimal fields, declared with [FixedWidthBinaryField]. Records are a fixed number of bytes with no newline delimiters, so FixedWidthBinaryLoader<T> writes them back-to-back and FixedWidthBinaryExtractor<T> reads them straight from the stream. Shows a symmetric write → read round trip and documents the EBCDIC code-page option.
MultiRecordTrailer
Routes a mainframe-style batch of interleaved header/detail/trailer records to different POCOs with FixedWidthMultiRecordExtractor (.When(line => line[0] == 'D', typeof(DetailRecord))), then validates the file's integrity: the trailer's declared record count and control total are compared against the details actually read. Shows that trailer-count validation is ordinary application logic on top of multi-record routing — no extra API required.