{"id":19626589,"url":"https://github.com/softcircuits/softcircuits.fixedwidthparser","last_synced_at":"2025-04-28T05:33:46.198Z","repository":{"id":65490995,"uuid":"312365025","full_name":"SoftCircuits/SoftCircuits.FixedWidthParser","owner":"SoftCircuits","description":"Lightweight .NET class for reading and writing fixed-width data files. Includes basic reader and writer class, and also includes generic classes that automatically map class properties to fixed-width fields. Includes many options to control the library's behavior.","archived":false,"fork":false,"pushed_at":"2024-03-31T16:24:12.000Z","size":259,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-14T03:08:51.661Z","etag":null,"topics":["file","file-parser","fixed","fixed-width","fixed-width-parser","text","text-parser","width"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SoftCircuits.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-12T18:39:32.000Z","updated_at":"2024-06-21T11:23:16.000Z","dependencies_parsed_at":"2023-01-25T18:35:11.457Z","dependency_job_id":null,"html_url":"https://github.com/SoftCircuits/SoftCircuits.FixedWidthParser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SoftCircuits%2FSoftCircuits.FixedWidthParser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SoftCircuits%2FSoftCircuits.FixedWidthParser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SoftCircuits%2FSoftCircuits.FixedWidthParser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SoftCircuits%2FSoftCircuits.FixedWidthParser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SoftCircuits","download_url":"https://codeload.github.com/SoftCircuits/SoftCircuits.FixedWidthParser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224098972,"owners_count":17255545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["file","file-parser","fixed","fixed-width","fixed-width-parser","text","text-parser","width"],"created_at":"2024-11-11T11:47:05.073Z","updated_at":"2024-11-11T11:47:06.486Z","avatar_url":"https://github.com/SoftCircuits.png","language":"C#","readme":"# Fixed-Width Parser\n\n[![NuGet version (SoftCircuits.FixedWidthParser)](https://img.shields.io/nuget/v/SoftCircuits.FixedWidthParser.svg?style=flat-square)](https://www.nuget.org/packages/SoftCircuits.FixedWidthParser/)\n\n```\nInstall-Package SoftCircuits.FixedWidthParser\n```\n\n## Overview\n\nSoftCircuits.FixedWidthParser is a lightweight .NET class for reading and writing fixed-width data files.\n\nFixed-width files are text files that contain one data record on each line. Fields for each record are not delimited. Instead, each field has a fixed width, or length, and fields are found by their location within the line.\n\nThe library includes basic classes for reading and writing fixed-width data files. And it also includes generic classes that automatically map class properties to fixed-width fields. The library also provides many options to control the library's behavior.\n\n----\n## Breaking Changes in Version 3.0.0\n\nThe method signatures for `FixedWidthReader.Read()`, `FixedWidthReader.ReadAsync()`, `FixedWidthReader\u003cT\u003e.Read()`, and `FixedWidthReader\u003cT\u003e.ReadAsync()` have changed. We were very reluctant to break existing code, but we believe these changes significantly simplify calling these methods. And the code changes should be very minimal.\n\nThe `FixedWidthReader.Read()` and `FixedWidthReader.ReadAsync()` now store the values in the `Values` property:\n\n``` cs\n// FixedWidthReader.Read()\nusing (FixedWidthReader reader = new(PersonFields, filename))\n{\n    while (reader.Read())\n    {\n        string[] values = reader.Values;\n    }\n}\n```\n\nSimilarly, the `FixedWidthReader\u003cT\u003e.Read()` and `FixedWidthReader\u003cT\u003e.ReadAsync()` now store the object read in the `Item` property:\n\n``` cs\n// FixedWidthReader\u003cT\u003e.Read()\nusing (FixedWidthReader\u003cPerson\u003e reader = new(filename))\n{\n    while (reader.Read())\n    {\n        Debug.Assert(reader.Item != null);\n        Person person = reader.Item;\n    }\n}\n```\n\nNote: The `Item` property is guaranteed not to be null when `FixedWidthReader\u003cT\u003e.ReadAsync()` returns true. However, .NET does not currently support the `MemberNotNullWhenAttribute` attribute for async methods. So the compiler may generate warnings when nullable reference types are enabled. In this case, you can safely use the null-forgiving operator (!) (or `Debug.Assert()` as shown above) when this method returns true.\n\n----\n\n## FixedWidthWriter and FixedWidthReader Classes\n\nThese classes provide the simplest way to read and write fixed-width data files. The example below writes several rows of data to a fixed-width file and then reads it back.\n\n```cs\n// Define fixed-width fields\nFixedWidthField[] PersonFields = new FixedWidthField[]\n{\n    new FixedWidthField(5),\n    new FixedWidthField(10),\n    new FixedWidthField(10),\n};\n\n// Write data to disk.\n// FixedWidthWriter.Write() is overloaded to also accept string[] and IEnumerable\u003cstring\u003e.\nusing (FixedWidthWriter writer = new(PersonFields, filename))\n{\n    writer.Write(\"1\", \"Bill\", \"Smith\");\n    writer.Write(\"2\", \"Karen\", \"Williams\");\n    writer.Write(\"3\", \"Tom\", \"Phillips\");\n    writer.Write(\"4\", \"Jack\", \"Carpenter\");\n    writer.Write(\"5\", \"Julie\", \"Samson\");\n}\n\n// Read the data from disk\nusing (FixedWidthReader reader = new(PersonFields, filename))\n{\n    while (reader.Read())\n    {\n        // reader.Values contains the values read\n    }\n}\n```\n\nThe code above writes and then reads the following file:\n\n```\n1    Bill      Smith     \n2    Karen     Williams  \n3    Tom       Phillips  \n4    Jack      Carpenter \n5    Julie     Samson    \n```\n\n## FixedWidthWriter\u0026lt;T\u0026gt; and FixedWidthReader\u0026lt;T\u0026gt; Classes\n\nThese classes are used to write and read objects to and from fixed-width data files. Object properties are automatically mapped to fixed-width fields.\n\nAll properties and fields in the class with a `FixedWidthField` attribute will be written and/or read to the fixed-width file. Note that the members don't have to be strings. All the basic data types are supported, including `DateTime` and `Guid`.\n\n```cs\n// Declare our class with FixedWidthField attributes.\n// Members without the FixedWidthField attribute will not be written or read.\nprivate class Product\n{\n    [FixedWidthField(36)]\n    public Guid Id { get; set; }\n    [FixedWidthField(12)]\n    public string Description { get; set; }\n    [FixedWidthField(12)]\n    public string Category { get; set; }\n    [FixedWidthField(10)]\n    public double Rating { get; set; }\n}\n\n// Create some data\nprivate readonly List\u003cProduct\u003e Products = new List\u003cProduct\u003e\n{\n    new Product { Id = Guid.NewGuid(), Description = \"Coffee Table\", Category = \"Furniture\", Rating = 4.5 },\n    new Product { Id = Guid.NewGuid(), Description = \"Spoons\", Category = \"Utensils\", Rating = 4.2 },\n    new Product { Id = Guid.NewGuid(), Description = \"Carpet\", Category = \"Flooring\", Rating = 4.5 },\n    new Product { Id = Guid.NewGuid(), Description = \"Knives\", Category = \"Utensils\", Rating = 4.7 },\n    new Product { Id = Guid.NewGuid(), Description = \"Recliner\", Category = \"Furniture\", Rating = 4.5 },\n    new Product { Id = Guid.NewGuid(), Description = \"Floor Tiles\", Category = \"Flooring\", Rating = 4.5 },\n};\n\n// Write the data to a file\nusing (FixedWidthWriter\u003cProduct\u003e writer = new(filename))\n{\n    foreach (var product in Products)\n        writer.Write(product);\n}\n\n// Read the data back from the file\nList\u003cProduct\u003e results = new();\nusing (FixedWidthReader\u003cProduct\u003e reader = new(filename))\n{\n    while (reader.Read())\n        results.Add(reader.Item);\n}\n```\n\nHere's the file created by the code above:\n\n```\n556348bf-058b-48fe-9a13-8ccc376f2e61Coffee TableFurniture   4.5       \n3e00e345-1844-4842-b707-168767fb0d5fSpoons      Utensils    4.2       \naae72fec-80f0-48de-8cc5-cd08268624c9Carpet      Flooring    4.5       \nce2026bf-7401-47b2-a7ab-2202292a4425Knives      Utensils    4.7       \n17f78e60-4909-4065-9574-d3f60ea55332Recliner    Furniture   4.5       \n2d1d4c05-e05b-43dd-bfd5-c0998c4b8312Floor Tiles Flooring    4.5       \n```\n\n## Writing Custom Converters\n\nIf you have a class member of a type for which there is no built-in support, or if you want to customize the way a member is formatted, you can supply your own data conversion class.\n\nOne example where you might need to do this is for `DateTime` fields. While the built-in `DateTime` converter works in many cases, date formats can vary wildly. So you might need a custom data converter to control exactly how these values are formatted.\n\nData conversion classes must implement the `IDataConverter` interface, but the easiest way to write a custom data converter in a type-safe manner is to derive your class directly from `DataConverter\u003cT\u003e`, where `T` is the type of the member you are converting. This class has two abstract members that you must implement in your derived class: `ConvertToString()` and `TryConvertFromString()`.\n\nThe following code reads and writes `Person` records, which contain a `DateTime` property. The `BirthDateConverter` class is used to provide data conversion support for the `DateTime` property. This is done by setting the `ConverterType` property of the `FixedWidthField` attribute.\n\n```cs\n// Define the Person class\nprivate class Person\n{\n    [FixedWidthField(8)]\n    public int Id { get; set; }\n    [FixedWidthField(12)]\n    public string FirstName { get; set; }\n    [FixedWidthField(12)]\n    public string LastName { get; set; }\n    [FixedWidthField(12, ConverterType = typeof(BirthDateConverter))]\n    public DateTime BirthDate { get; set; }\n}\n\n// Define our date converter class\nprivate class BirthDateConverter : DataConverter\u003cDateTime\u003e\n{\n    private const string Format = \"yyyyMMdd\";\n\n    public override string ConvertToString(DateTime value) =\u003e value.ToString(Format);\n\n    public override bool TryConvertFromString(string? s, out DateTime value)\n    {\n        return DateTime.TryParseExact(s, Format, null, System.Globalization.DateTimeStyles.None, out value);\n    }\n}\n\n// Define some Person data\nprivate readonly List\u003cPerson\u003e People = new()\n{\n    new Person { Id = 1, FirstName = \"Bill\", LastName = \"Smith\", BirthDate = new DateTime(1982, 2, 7) },\n    new Person { Id = 1, FirstName = \"Gary\", LastName = \"Parker\", BirthDate = new DateTime(1989, 8, 2) },\n    new Person { Id = 1, FirstName = \"Karen\", LastName = \"Wilson\", BirthDate = new DateTime(1978, 6, 24) },\n    new Person { Id = 1, FirstName = \"Jeff\", LastName = \"Johnson\", BirthDate = new DateTime(1972, 4, 18) },\n    new Person { Id = 1, FirstName = \"John\", LastName = \"Carter\", BirthDate = new DateTime(1982, 12, 21) },\n};\n\n// Write the data to a file\nusing (FixedWidthWriter\u003cPerson\u003e writer = new(filename))\n{\n    foreach (var person in People)\n        writer.Write(person);\n}\n\n// Read the data back from the file\nList\u003cPerson\u003e results = new();\nusing (FixedWidthReader\u003cPerson\u003e reader = new(filename))\n{\n    while (reader.Read())\n        results.Add(reader.Item);\n}\n```\n\nHere's the file created by the code above:\n\n```\n1       Bill        Smith       19820207    \n1       Gary        Parker      19890802    \n1       Karen       Wilson      19780624    \n1       Jeff        Johnson     19720418    \n1       John        Carter      19821221    \n```\n\nThe library defines the following custom data converters that you can use as the converter type.\n\n- `CompactDateTimeConverter` (DateTime)\n- `DateOnlyDateTimeConverter` (DateTime)\n- `UniversalDateTimeConverter` (DateTime)\n\n## Manual Field Mapping\n\nWhen using the `FixedWidthReader\u003cT\u003e` and `FixedWidthWriter\u003cT\u003e` classes, it's possible that you need to work with a class that you cannot modify. In this case, you won't be able to add `FixedWidthFieldAttribute` attributes to the properties you want to serialize.\n\nYou can work around this by manually mapping fields using the `FixedWidthReader\u003cT\u003e.MapField()` and `FixedWidthWriter\u003cT\u003e.MapField()` methods. These methods will instruct the library how to map class members to fixed-width columns.\n\n```cs\nusing (FixedWidthWriter\u003cPerson\u003e writer = new(filename))\n{\n    writer.MapField(m =\u003e m.Id, 8);\n    writer.MapField(m =\u003e m.FirstName, 12);\n    writer.MapField(m =\u003e m.LastName, 12);\n    writer.MapField(m =\u003e m.BirthDate, 12).SetConverterType(typeof(BirthDateConverter));\n}\n```\n\nAs you can see from the last line, the `MapField()` method supports a Fluent interface to set additional mapping properties.\n\nIf you call the `MapField()` method for a property that is already mapped (whether from a previous call to `MapField()` or from a `FixedWidthFieldAttribute` attribute), the settings will override the existing map settings. However, if you call `MapField()` for a property that is not already mapped, that field will be appended as the last fixed-width field. So the order fields are mapped will set the order of the fixed-width fields in the output/input file.\n\n## Additional Field Options\n\nWhether you define your fields by declaring an array of `FixedWidthField`s or using the `FixedWidthField` attribute, there are a number of field options you can specify.\n\n#### int Length\n\nGets or sets the number of characters occupied by this column.\n\n#### FieldAlignment? Alignment\n\nGets or sets the column alignment for this field. Leave as `null` to use the default alignment.\n\n#### char? PadCharacter\n\nGets or sets the character used to pad this field when writing values shorter than the field width. Leave as `null` to use the default pad character.\n\n#### bool? TrimField\n\nGets or sets whether leading and trailing pad characters are trimmed when reading field values. Leave as `null` to use the default trim setting.\n\nWARNING: If this property is \u003cc\u003etrue\u003c/c\u003e and the field value contains leading or trailing characters that match the current pad character, those characters will also be trimmed.\n\n#### int Skip\n\nGets or sets the number of characters to skip before the field. Normally, this property is set to zero. You can use this property to skip fixed-width fields that you don't want to read. When writing fixed-width files, the character specified by `FixedWidthOptions.DefaultPadCharacter` will be written to fill the skipped characters. The default value is `0`.\n\n#### Type ConverterType\n\nGets or sets the data type that converts this field to and from a string (as demonstrated previously). Must derive from `IDataConverter`. For best results and type safety, derive the class from `DataConverter\u003cT\u003e`.\n\nThis property is available with the `FixedWidthField` attribute and not the `FixedWidthField` class.\n\n## Customizing the Library\n\nAll of the constructors for the `FixedWidthReader`, `FixedWidthReader\u003cT\u003e`, `FixedWidthWriter`, and `FixedWidthWriter\u003cT\u003e` class have an optional `FixedWidthOptions` parameter. To use the default options, leave this parameter as `null`. Provide your own instance of this class to customize the library settings.\n\n```cs\n// Set to right align, tilde padding and don't throw exception for invalid data\nFixedWidthOptions options = new FixedWidthOptions\n{\n    DefaultAlignment = FieldAlignment.Right,\n    DefaultPadCharacter = '~',\n    ThrowDataException = false\n};\n\nusing (FixedWidthWriter\u003cProduct\u003e writer = new FixedWidthWriter\u003cProduct\u003e(filename, options))\n{\n    foreach (var product in Products)\n        writer.Write(product);\n}\n```\n\nThe `FixedWidthOptions` class has the following properties.\n\n#### FieldAlignment DefaultAlignment\n\nGets or sets the default way fields are padded. For example, if a field is right aligned, values shorter than the field width are padded on the left. Can be overridden for individual fields using the `FixedWidthField.Alignment` property. The default value is `FieldAlignment.Left`.\n\n#### char DefaultPadCharacter\n\nGets or sets the default character used to pad fields when writing values shorter than the field width. Can be overridden for individual fields using the `FixedWidthField.PadCharacter` property. The default value is `' '`.\n\n#### bool TrimFields\n\nGets or sets whether leading and trailing pad characters are trimmed when reading field values. Can be overridden for individual fields using the `FixedWidthField.TrimField` property. The default value is `true`.\n\nWARNING: If this property is \u003cc\u003etrue\u003c/c\u003e and the field value contains leading or trailing characters that match the current pad character, those characters will also be trimmed.\n\n#### bool ThrowDataException\n\nGets or sets whether a `FixedWidthDataException` is thrown when reading a field that cannot be converted to the target field type. The default value is `true`.\n\n#### bool ThrowOutOfRangeException\n\nGets or sets whether a `FixedWidthOutOfRangeException` is thrown when reading a field from a line that is too short. If `false`, the library reads as much of the field as possible or returns an empty string. The default value is `true`.\n\n#### bool ThrowOverflowException\n\nGets or sets whether a `FixedWidthOverflowException` is thrown when attempting to write a value that is too large for the field. If `false`, the value will be silently truncated. The default value is `true`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftcircuits%2Fsoftcircuits.fixedwidthparser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftcircuits%2Fsoftcircuits.fixedwidthparser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftcircuits%2Fsoftcircuits.fixedwidthparser/lists"}