Fixed-Width Data
Fixed-width data files store tabular, textual data in a format that is common to many different systems. This can allow information to easily be shared by software than cannot be integrated by other means. The style of storage is named because individual elements or fields of data have a fixed width. For example, you might wish to store the details of employees with data for forename, surname, age and salary. You might decide to use widths of fifteen characters each for the two names, three characters for the age and five for the salary. Where the data does not fill the allocated space, the items are padded, often with spaces.
The following shows some sample data with this fixed-width layout:
Andrew Green 25 26000
Ben Brown 32 28500
Celia Black 29 28000
Steve Pink 41 52000
In this article we'll create a class that allows you to easily generate fixed-width data. It will be similar in operation to the CSV writer class I described in an earlier article.
Creating the Class
As with the CSV writer class we'll base the fixed-width writer on the standard StreamWriter type. This includes all of the functionality we'll need for writing text to streams and files, allowing us to concentrate only on the elements required for fixed-width data.
To begin, create a new console application and add a class named FixedWidthWriter. Make the class public and inherit from StreamWriter as follows:
public class FixedWidthWriter : StreamWriter
{
}
StreamWriter is found in the System.IO namespace, so add the following using directive to the new class:
Configuration
To allow the output of the new class to be controlled we need two configuration options. Firstly we need to be able to specify the widths of the columns. We could pass these to the method that writes the data. However, in this case we'll use a property and allow the value to be set in the class's constructor. This will ensure that, unless overridden part way through a file's output, the column widths will remain the same for all lines. The second property holds the character to use to pad data that does not completely fill the allocated width. This one isn't set in the constructor; it simply defaults to a space, as this is the most common option.
Add the properties and constructor as follows. Note that some additional parameters are included. These are passed to the base constructor provided by the StreamWriter class. they control whether new data is appended to existing files and the encoding option for the text.
public int[] Widths { get; set; }
public char NonDataCharacter { get; set; }
public FixedWidthWriter(int[] widths, string path, bool append, Encoding encoding)
: base(path, append, encoding)
{
NonDataCharacter = ' ';
Widths = widths;
}
To simplify the general use of FixedWidthWriter we can add two further constructors. Each has fewer parameters and calls the original constructor with default values.
public FixedWidthWriter(int[] widths, string file)
: this(widths, file, false, Encoding.UTF8) { }
public FixedWidthWriter(int[] widths, string file, bool append)
: this(widths, file, append, Encoding.UTF8) { }
4 May 2013