Roadmap › C# Language — Basics to Advanced › Module: Files and Streams
Lessons in this course (38)

33. Streams, StreamReader/StreamWriter and async file I/O

IntermediateMediumLesson 33 of 38

A stream is a sequence of bytes you read or write piece by piece, so huge files never need to fit in memory. Stream is the abstract base for FileStream, MemoryStream, NetworkStream, BufferedStream, GZipStream, CryptoStream…

csharp
// Text: StreamWriter / StreamReader wrap a stream and handle encoding (UTF-8 by default)
using (var writer = new StreamWriter("log.txt", append: true))
{
    writer.WriteLine($"{DateTime.UtcNow:O} Started");
}   // Dispose flushes and closes the file

using var reader = new StreamReader("big.csv");
string? line;
long count = 0;
while ((line = await reader.ReadLineAsync()) != null)   // streams line by line
    if (line.Contains("ERROR")) count++;

// Bytes: FileStream with explicit options
await using var fs = new FileStream("photo.jpg", FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 81920, useAsync: true);
var buffer = new byte[81920];
int read;
while ((read = await fs.ReadAsync(buffer)) > 0) { /* process buffer[..read] */ }

// Copy one stream into another (e.g. upload → Blob storage, file → HTTP response)
await using var source = File.OpenRead("report.pdf");
await using var target = File.Create("copy.pdf");
await source.CopyToAsync(target);

// MemoryStream: a stream over a byte[] in memory — handy for tests and in-memory files
using var ms = new MemoryStream();
await JsonSerializer.SerializeAsync(ms, new { Id = 1 });
byte[] json = ms.ToArray();

// Compression by chaining streams
await using var zip = new GZipStream(File.Create("data.gz"), CompressionLevel.Optimal);
await using var zipWriter = new StreamWriter(zip);
await zipWriter.WriteAsync("compressed text");
ClassPurpose
FileStreamRead/write bytes in a file (FileMode: Create, Open, Append, OpenOrCreate)
StreamReader / StreamWriterText on top of any stream, with encoding
BinaryReader / BinaryWriterPrimitive types as binary
MemoryStreamIn-memory byte buffer
BufferedStream, GZipStream, CryptoStreamDecorators that add buffering, compression, encryption

Interview tip: Always dispose streams (using / await using) — otherwise file handles stay locked and buffered data may never be written. Use async I/O in web apps so threads aren't blocked while waiting for the disk.