Welcome to Atalasoft Community Sign in | Help

C# NullStream

I've always been a big fan of the UNIX concept of /dev/null.  It's a file/device that can accept an infinite amount of data without growing and when read always returns end-of-file.  It is conceptually a data sink.

I was surprised that .NET (at least 1.1) doesn't have that as a derived class from Stream.  That being the case, here is just such an implementation for you.  I'm using it in a unit test that generates huge amounts of data into a stream.  Since I care about the process of data generation and not the actual data itself, it's way more efficient to have a perfect sink for the data.  In this case, the stream class maintains a position and length, but tracks no data beyond that.

using System;
using System.IO;

namespace Atalasoft.Tests
{
    public class NullStream : Stream
    {
        long _position = 0;
        long _length = 0;

        public NullStream()
        {
        }

        public override bool CanRead { get { return false; } }
        public override bool CanWrite { get { return true; } }
        public override bool CanSeek { get { return true; } }

        public override void Flush() { }

        public override long Length { get { return _length; } }
        public override long Position
        {
            get { return _position; }
            set
            {
                _position = value;
                if (_position > _length)
                    _length = _position;
            }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            long newPosition = Position;

            switch (origin)
            {
                default:
                case SeekOrigin.Begin:
                    newPosition = offset;
                    break;
                case SeekOrigin.Current:
                    newPosition = Position + offset;
                    break;
                case SeekOrigin.End:
                    newPosition = Length + offset;
                    break;
            }
            if (newPosition < 0)
                throw new ArgumentException("Attempt to seek before start of stream.");
            Position = newPosition;
            return newPosition;
        }

        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            throw new NotImplementedException("This stream doesn't support reading.");
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            throw new NotImplementedException("This stream doesn't support reading.");
        }

        public override void SetLength(long value)
        {
            _length = value;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            Seek((long)count, SeekOrigin.Current);
        }
    }
}

Published Friday, September 15, 2006 5:12 PM by Steve Hawley

Comments

No Comments
Anonymous comments are disabled