Skip Navigation LinksHome > View Post

Working with streams

I'm always looking for these snippets so I'm going to blog them for ease of look up in the future. Maybe it will prove of use to some readers out there too.

public static class StreamHelper
{
    private const int SIZE = 4096;

    /// <summary>
    /// Creates a copy of the passed stream and returns the clone to position 0.
    /// </summary>
    /// <param name="source">The Stream to be copied</param>
    /// <returns>A copy of the source stream</returns>
    public static Stream CloneStreamAndReturnToStart(Stream source)
    {
        Stream clone = new MemoryStream();
        CloneStream(source, clone);
        clone.Seek(0, SeekOrigin.Begin);
        return clone;
    }

    /// <summary>
    /// Copies the contents of one stream to another. Note the output stream will be left at the last
    /// position and may require a seek before it is used.
    /// </summary>
    /// <param name="input">The stream to copy</param>
    /// <param name="output">The target stream</param>
    public static void CloneStream(Stream input, Stream output)
    {
        byte[] bytes = new byte[SIZE];
        int numBytes;
        while ((numBytes = input.Read(bytes, 0, SIZE)) > 0)
        {
            output.Write(bytes, 0, numBytes);
        }
    }

    /// <summary>
    /// Reads all bytes from a stream and returns a byte array
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    public static byte[] ReadAllBytes(Stream stream)
    {
        byte[] buffer = new byte[SIZE];
        int read = 0;

        int numBytes;
        while ((numBytes = stream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += numBytes;

            // If we've reached the end of our buffer, check to see if there's
            // any more information
            if (read == buffer.Length)
            {
                int nextByte = stream.ReadByte();

                // End of stream? If so, we're done
                if (nextByte == -1)
                {
                    return buffer;
                }

                // Nope. Resize the buffer, put in the byte we've just
                // read, and continue
                byte[] newBuffer = new byte[buffer.Length * 2];
                Array.Copy(buffer, newBuffer, buffer.Length);
                newBuffer[read] = (byte)nextByte;
                buffer = newBuffer;
                read++;
            }
        }
        // Buffer is now too big. Shrink it.
        byte[] ret = new byte[read];
        Array.Copy(buffer, ret, read);
        return ret;
    }
}

If anyone knows of an easier way to do this using methods hidden away in the Framework somewhere, please leave a comment.

Tags: C#

 
Josh Post By Josh Twist
1:01 AM
21 Apr 2008

» Next Post: Introducing Ukadc.Diagnostics
« Previous Post: Xaml for Config

Comments are closed for this post.

Posted by Ian @ 21 Apr 2008 5:34 AM
I had this same problem a year and a half ago. I could not find any examples to copy streams, let alone return the original. I didn't have the option to post the code. Thanks.

Posted by Pete weissbrod @ 21 Apr 2008 8:00 AM
NICE!

we need a ".NET Framework Contrib" project to throw pieces like this into... thanks, I've written this a few times before, definitely useful

Posted by Josh @ 21 Apr 2008 8:01 AM
Yes... somebody's already suggested that these should be extension methods and that's definitely a great idea (if you have 3.5fx at your disposal anhyhow).

Josh

© 2005 - 2014 Josh Twist - All Rights Reserved.