tags:

views:

1488

answers:

4

What's the most efficient way to read a stream into another stream? In this case, I'm trying to read data in a Filestream into a generic stream. I know I could do the following:
1. read line by line and write the data to the stream
2. read chunks of bytes and write to the stream
3. etc

I'm just trying to find the most efficient way.

Thanks

A: 

Reading a buffer of bytes and then writing it is fastest. Methods like ReadLine() need to look for line delimiters, which takes more time than just filling a buffer.

HTH, Kent

Kent Boogaart
+2  A: 

Stephen Toub discusses a stream pipeline in his MSDN .NET matters column here. In the article he describes a CopyStream() method that copies from one input stream to another stream. This sounds quite similar to what you're trying to do.

Jeff Stong
I really liked that article for the parallel tasks perspective, but that stream copy is pretty useful in its own right. However, if the stream does support the Length property (if CanSeek is false, exception), the buffer should be the length of the input stream and be done in a single read.
Jesse C. Slicer
A: 

I assume by generic stream, you mean any other kind of stream, like a Memory Stream, etc.

If so, the most efficient way is to read chunks of bytes and write them to the recipient stream. The chunk size can be something like 512 bytes.

C. Lawrence Wenham
+4  A: 

I rolled together a quick extension method (so VS 2008 w/ 3.5 only):

public static class StreamCopier
{
   private const long DefaultStreamChunkSize = 0x1000;

   public static void CopyTo(this Stream from, Stream to)
   {
      if (!from.CanRead || !to.CanWrite)
      {
         return;
      }

      var buffer = from.CanSeek
         ? new byte[from.Length]
         : new byte[DefaultStreamChunkSize];
      int read;

      while ((read = from.Read(buffer, 0, buffer.Length)) > 0)
      {
        to.Write(buffer, 0, read);
      }
   }
}

It can be used thus:

 using (var input = File.OpenRead(@"C:\wrnpc12.txt"))
 using (var output = File.OpenWrite(@"C:\wrnpc12.bak"))
 {
    input.CopyTo(output);
 }

You can also swap the logic around slightly and write a CopyFrom() method as well.

Jesse C. Slicer