Reading fixed-width data fields in .NET I'm working on a communications layer for a system that reads data from a TCPIP client that is formatted as fixed-width ASCII (yeah, old school). I was quite surprised that there seemed to be no built in way to do this, and ended up using the following simple StreamReader subclass:

/// &lt;summary&gt;
/// A Stream reader that reads values as fixed width fields from a stream
/// &lt;/summary&gt;
class FixedWidthFieldStreamReader : StreamReader
{
    #region Private/Protected fields
    private char[] buffer; // Local buffer used to copy data before conversion
    #endregion

    #region Methods
    /// &lt;summary&gt;
    /// Instantiates a new FixedWidthFieldStreamReader for a stream
    /// &lt;/summary&gt;
    /// &lt;param name="stream"&gt;Stream to read from&lt;/param&gt;
    /// &lt;param name="initialBufferSize"&gt;Initial size of the buffer used to copy data before formatting&lt;/param&gt;
    /// &lt;param name="encoding"&gt;Encoding to use when reading from the stream&lt;/param&gt;
    public FixedWidthFieldStreamReader(Stream stream, int initialBufferSize, Encoding encoding)
        : base(stream, encoding)
    {
        buffer = new char[initialBufferSize];
    }

    /// &lt;summary&gt;
    /// Checks if the buffer exists and is large enough,
    /// and allocates or grows it if necessary.
    /// &lt;/summary&gt;
    /// &lt;param name="length"&gt;The required buffer length&lt;/param&gt;
    private void EnsureBufferLength(int length)
    {
        if (null == buffer ||
            buffer.Length &lt; length)
        {
            buffer = new char[length];
        }
    }

    /// &lt;summary&gt;
    /// Reads a number of bytes into the buffer
    /// &lt;/summary&gt;
    /// &lt;param name="length"&gt;The number of bytes to read&lt;/param&gt;
    /// &lt;returns&gt;True if the required number of bytes was read, false otherwise&lt;/returns&gt;
    private bool ReadToBuffer(int length)
    {
        EnsureBufferLength(length);

        // Read from the stream
        int read = Read(buffer, 0, length);
        return read == length;
    }

    /// &lt;summary&gt;
    /// Reads a specified number of bytes from the stream and 
    /// converts and returns the read value.
    /// &lt;/summary&gt;
    /// &lt;typeparam name="T"&gt;Type of the object to read and return&lt;/typeparam&gt;
    /// &lt;param name="length"&gt;Number of bytes in the field to read from the stream.&lt;/param&gt;
    /// &lt;returns&gt;The read object if successful, or the default value for the type otherwise.&lt;/returns&gt;
    public T Read&lt;T&gt;(int length) where T : IConvertible
    {
        if (ReadToBuffer(length))
        {
            return (T)Convert.ChangeType(new string(buffer, 0, length), typeof(T));
        }

        return default(T);
    }

    /// &lt;summary&gt;
    /// Skips a specified number of bytes in the stream
    /// &lt;/summary&gt;
    /// &lt;param name="length"&gt;The number of bytes to skip&lt;/param&gt;
    public void Skip(int length)
    {
        // Ideally we should be able to just seek on the current stream, 
        //  but that seems to seek to an incorrect location?
        //this.BaseStream.Seek(length, SeekOrigin.Current);
        ReadToBuffer(length);
    }
    #endregion
}


This would be used something like this:

using (MemoryStream stream = new MemoryStream(buffer))
{
    stream.Seek((int)FieldOffsets.DATA, SeekOrigin.Begin);
    using (FixedWidthFieldStreamReader reader = new FixedWidthFieldStreamReader(stream, 15, Encoding.ASCII))
    {
        intVal = reader.Read&lt;int&gt;(3);
        stringVal = reader.Read&lt;string&gt;(15);
        floatVal= reader.Read&lt;float&gt;(5);
    }
}


I have two questions based on this:


Am I just missing some completely obvious existing utility to do this? It really does seem like a common problem that would have been solved by the framework team ages ago.
Aside from the obvious optimization of having some type specific versions of Read that don't do the conversion, are there any suggestions to improve this approach?
I don't know if something does that already, but you could mimic StructLayout if you need to read multiple types of 'objects' or need reusability.

Basically just set starting point/offset and length for each property and read them.

public class Item
{
     // 3 chars starting from 0
    [Layout(0, 3)]
    public int Number { get; set; }

     // 15 chars starting from 3
    [Layout(3, 15)]
    public string Text { get; set; } 

    // 5 chars starting from 18
    [Layout(18, 5)]
    public float Number2 { get; set; } 
}

reader.Read&lt;Item&gt;()