To create a byte array from a stream in C#, you can read the stream’s data and store it in a byte[]. Below are detailed methods and examples to handle different scenarios, including streams that are seekable (e.g., FileStream, MemoryStream) and non-seekable (e.g., NetworkStream).
Method 1: Using MemoryStream and CopyTo (Recommended for .NET 4.0+)
This method efficiently copies the stream into a MemoryStream and returns the byte array.
public static byte[] ReadAllBytes(Stream stream)
{
    if (stream == null)
        throw new ArgumentNullException(nameof(stream));
    // If the stream is already a MemoryStream, directly return its byte array
    if (stream is MemoryStream memoryStream)
        return memoryStream.ToArray();
    // Save the original position (for seekable streams)
    long originalPosition = 0;
    if (stream.CanSeek)
    {
        originalPosition = stream.Position;
        stream.Position = 0; // Reset position to read from the start
    }
    try
    {
        using (var ms = new MemoryStream())
        {
            stream.CopyTo(ms); // Copy stream data to MemoryStream
            return ms.ToArray();
        }
    }
    finally
    {
        // Restore the original position (for seekable streams)
        if (stream.CanSeek)
            stream.Position = originalPosition;
    }
}Method 2: Manual Read in Chunks (Works for All .NET Versions)
This method reads the stream in chunks to handle large files and non-seekable streams.
public static byte[] ReadAllBytes(Stream stream)
{
    if (stream == null)
        throw new ArgumentNullException(nameof(stream));
    byte[] buffer = new byte[16 * 1024]; // 16KB buffer
    using (var ms = new MemoryStream())
    {
        int bytesRead;
        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, bytesRead); // Write chunks to MemoryStream
        }
        return ms.ToArray();
    }
}Examples
Example 1: Convert a FileStream to a Byte Array
using (FileStream fileStream = File.OpenRead("example.txt"))
{
    byte[] bytes = ReadAllBytes(fileStream);
    // Use the byte array (e.g., save to a database)
}Example 2: Convert a NetworkStream to a Byte Array
TcpClient client = new TcpClient("example.com", 80);
using (NetworkStream networkStream = client.GetStream())
{
    byte[] bytes = ReadAllBytes(networkStream); // Reads until stream ends
}Example 3: Directly Use MemoryStream
byte[] data = Encoding.UTF8.GetBytes("Hello, World!");
using (MemoryStream memoryStream = new MemoryStream(data))
{
    byte[] bytes = ReadAllBytes(memoryStream); // Returns the original data
}Key Considerations
- Stream Position:
- For seekable streams (e.g., FileStream,MemoryStream), reset the position to0to read from the start.
- For non-seekable streams (e.g., NetworkStream), read from the current position until the end.
- Memory Efficiency:
- Use chunked reading (e.g., 16KBbuffer) for large streams to avoid high memory usage.
- Stream Ownership:
- The method does not close/dispose the input stream. Handle disposal via usingblocks.
- Edge Cases:
- Handle exceptions (e.g., IOException,NotSupportedException).
- Validate if the stream is readable (stream.CanRead).
Performance Comparison
| Method | Use Case | Pros | Cons | 
|---|---|---|---|
| CopyTo+MemoryStream | Modern .NET (4.0+) | Simple, optimized for speed. | Requires .NET 4.0+. | 
| Chunked Read | Legacy .NET or large streams | Works in all .NET versions, memory-safe. | Slightly more code. | 
Summary
- Use stream.CopyTo(ms)for modern .NET to convert streams to byte arrays.
- Use chunked reading for backward compatibility or large streams.
- Always handle stream positions and exceptions for reliability.