c# – How to Really Understand Streams?

Question:

I've been working with C# and .NET for a while and I've seen the use of streams out there for reading files, writing HTML response, uploading files, etc. It turns out that I still haven't understood what a stream really is, when they should be used or how it works.

For example, to read a file we use the following:

using (StreamReader streamReader = new StreamReader(caminhoArquivo))
{
    string conteudo = streamReader.ReadToEnd();
}

Another example is uploading data to a Microsoft Azure blob

using (Stream stream = File.OpenRead(caminhoArquivo))
{
    blockBlob.UploadFromStream(stream);
} 

And another example, which doesn't involve files, is writing the content of an HTTP response in an OWIN middleware. Searching a little about streams I found the following:

We have an abstract class that represents a sequence of bytes on which we can perform read and write operations. This abstract class is called a Stream.

So a stream is a sequence of bytes? Still, when should this be used? Why in these cases I mentioned we use streams? In case the HTTP response is even a little harder to understand, couldn't we just write the response text instead of a stream?

Answer:

Almost that. Stream is a sequence of data, of elements. These can be bytes , the most common, but not necessarily. Individual elements can be more complex or simpler objects, such as the bit . If we were to translate the word, we would probably call it continuous flow. It's just a concept.

Flow is the key word there. The stream is created precisely to avoid having to deal with the whole. With it, it is possible to manipulate the desired data on demand.

With stream the application works with a connection model always. The code initiates the connection by opening the stream and can use it until it is closed by the code, eventually decided through signaling received during the process. The connection doesn't have to be an external mechanism, it just has a data collection.

Benefits

These data may or may not be available as a whole. It can come/go little by little solving a potential problem of memory overload (of any kind), congestion and temporary lack of transmission. As long as the stream is open and gives no indication that it has ended it can provide new data even if a wait is required.

Another advantage is that you don't need to know how information comes/goes, no matter the source or target. You don't need to know that the stream works a certain way. If the data source/target is a file on disk, in memory, or object in memory, a network transmission in any protocol, a database connection, a communication with another process, an algorithm that generates this data on demand (random numbers, for example) or otherwise, this is data source/target problem with stream .

The program that will consume the stream doesn't need to know how the data gets to it. That's why it's called an abstract class (nothing to do with OOP's abstract , although this mechanism is used in OO languages ​​to implement it). You don't need to know the concrete implementation of the data source/target. You also don't need to know which mode is used to deliver data. Several mechanisms can be used within it without the stream's consumer code needing to be aware.

Perhaps an example cited that could be explained is the generation of random items. Generating random numbers does not mean that the generator is a stream . As well as generating a string, it is not. The stream encapsulates data. So a random generator can be the stream's data source but not the stream itself. We cannot call any sequence of stream elements, it needs to comply with the protocol established by it.

A stream can even manipulate data in certain situations if there is some reason its mechanism provides something like that. Yet the programmer doesn't need to know internally how and why he does this, he just needs to understand how data comes and goes through it.

APIs that accept stream

In theory if an API wants to provide a way to work with data without the stream there is no problem. An HTTP response could work directly with the text, but it would lose all of the aforementioned advantages. For example, System.IO.File.WriteAllText() does not work with stream .

Obviously if the API only supports communication via streams you will have to do it this way. Overall there are only advantages to using it this way.

Disadvantage

Perhaps someone could say that there is a disadvantage to having an extra layer, which slightly increases the complexity and processing consumption. But they are very small things that are not usually relevant in terms of the advantages presented by their use. I will emphasize that the extra cost of its use is minimal in every way.

A real implementation example

Maybe analyzing the code of the Stream class can help (or hinder :)) to understand how it works. Note that it is just the basis for classes that actually provide concrete streams , that know how to handle certain sources/targets. It might be interesting to look at the code of some classes that inherit from it, such as FileStream .

Scroll to Top