In this article, we’ll discuss how to convert a stream to a file in C#. We will demonstrate different ways to do that, discuss the advantages and disadvantages of each, and see when one way could be more suitable.  

To download the source code for this article, you can visit our GitHub repository.

Let’s dive in.

What Is a Stream

A stream is an abstraction of a sequence of bytes. The Stream class in .NET is an abstract class that implements the methods enabling stream operations, such as reading and writing to streams and positioning in a stream, among others. 

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

The source and the destination of the sequence of the bytes can be various. For example, it can be a file, different input or output device, network, or similar. .NET implements a few classes that derive from the Stream class and deal with these different sources and destinations for a stream. That includes FileStream, MemoryStream, NetworkStream, and other classes. 

The Stream class and derived classes implement numerous methods for reading and writing from a stream, such as Read(), ReadAsync(), ReadByte(), Write(), WriteAsync(), and WriteByte().

How to Convert a Stream to a File in C#

Let’s describe several ways to convert a stream to a file in C#. First, we need to prepare our stream and path for a file:

var sourceFile = Path.Combine([directory, "Files", "source.png"]);
var destinationPath = Path.Combine([directory, "Files"]);

using var fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
using var memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);

The source image is in the Files subfolder. We will store the resulting file in the same folder. We load the source image to a FileStream and copy this stream to a MemoryStream. This MemoryStream is the input parameter for all methods where we convert it to a file. The second parameter of this method is a path for the destination file. 

Convert a Stream to a File Using CopyTo

The CopyTo() method of the Stream class copies from one stream to another:

public static void CopyToFile(MemoryStream stream, string path)
{
    using var fileStream = File.Create(path);
    stream.Position = 0;
    stream.CopyTo(fileStream);
}

We create a FileStream using the File.Create() method. The parameter of this method is the path where we want to save our file. After that, we position our source stream to 0 and then call the CopyTo() method on the Stream class.

Convert a Stream to a File Using Write

The FileStream.Write() method accepts a ReadOnlySpan<byte> argument and writes it to a file:

public static void WriteToFileStream(MemoryStream stream, string path)
{
    using var fileStream = File.Create(path);
    fileStream.Write(stream.ToArray());
}

First, we convert the input stream to a byte[]. The ToArray() method of the MemoryStream class converts the stream content to an array entirely. In this case, we don’t have to position the input stream to 0 before writing to a file, as the ToArray() method writes the entire stream content to an array, regardless of the position.  The Write() method then implicitly converts this array to a ReadOnlySpan<byte> and writes all bytes to a destination fileStream stream.

Convert a Stream to a File Using WriteByte

The FileStream class has the WriteByte() method which accepts one byte that it then writes to another stream:

public static void WriteByteToFileStream(MemoryStream stream, string path)
{
    using var fileStream = File.Create(path);
    stream.Position = 0;
    while (stream.Position < stream.Length)
    {
        fileStream.WriteByte((byte)stream.ReadByte());
    }
}

After creating the destination fileStream stream and positioning it at the first byte, we start a loop where we read one byte at a time with the ReadByte() method. This method returns an int value, so we must convert it to a byte data type that we write to the destination stream. 

Convert a Stream to a File Using WriteAllBytes

The File class has a static WriteAllBytes() method that accepts the path and an array of bytes to write to the file:

public static void WriteAllBytesFile(MemoryStream stream, string path)
{
    File.WriteAllBytes(path, stream.ToArray());
}

We pass the destination path to the static method and convert the input stream to the byte array. 

We often have to convert a stream to a byte array. In our article How to Convert Stream to a Byte Array in C#, you can learn different ways to do that.

Benchmark of Converting Stream to File

In addition, we’ll benchmark each of these examples to see the best way to perform this conversion from a performance perspective:

| Method                 | Mean     | Error    | StdDev   | Median   | Allocated |
|----------------------- |---------:|---------:|---------:|---------:|----------:|
| CopyToBenchmark        | 125.5 us |  2.46 us |  3.28 us | 125.1 us |     672 B |
| WriteAllBytesBenchmark | 133.1 us |  2.61 us |  5.33 us | 133.4 us |     520 B |
| WriteByteBenchmark     | 135.9 us |  2.97 us |  7.92 us | 135.4 us |     680 B |
| WriteBenchmark         | 144.5 us | 10.55 us | 29.93 us | 129.4 us |     672 B |

As we can see, all methods perform approximately the same. However, the CopyTo() method is a little bit faster. Moreover, if we run benchmark tests several times, other methods, except CopyTo(), perform slightly differently and not necessarily in this order. 

From a memory consumption perspective, the WriteAllBytes() method is the least demanding. 

Conclusion

Summing up, we have several options for converting a stream to a file in C#. However, all of these options are very similar, and using them may only be a matter of personal preference. 

A slightly more performant method is the Stream.CopyTo() method, but the File.WriteAllBytes() method is the best when we look at memory consumption. 

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!