Streams in C#

16 september 2022 om 10:00 by ParTech Media - Post a comment

In this digital era, there are thousands of manual activities that have been automated successfully. A classic example is writing and editing documents.

Unlike in the past, it is now a child’s play to correct mistakes and make changes while typing and proofreading.

But how do you do it in the C# programming language? That’s where Streams come into the picture. In this post, let us understand everything about this unique concept of C# that has made the lives of developers much simpler.

Table of contents

  1. Introduction to Streams
  2. Types of Streams
  3. Implementation of Streams
  4. Conclusion

Introduction to Streams

A stream is a wrapper or an abstract class that provides the required methods to read, write, and perform other relevant operations with bytes. To perform operations with bytes, a class has to implement the Stream class.

In file transfer, the Stream class acts as a layer between the application and the file. Streams also act as a memory management unit and enhance the performance of the application. While performing a read/write operation, the contents of the file are first transferred to the streams. Then, from the streams, a manageable set of chunks are read by the application.

Types of Streams

Here are the different types of Streams available in C#:

  • File Stream - helps in reading/writing content from/to a physical file (it could be of any format).
  • Memory Stream - helps in reading/writing content from/to memory.
  • Buffered Stream - helps in reading/writing content from another Stream.
  • Network Stream - helps in reading/writing content from/to network socket.
  • Pipe Stream - helps in reading/writing content from/to the pipes.
  • Crypto Stream - helps in linking data streams with cryptographic transformations,

Now, let us dig a little deeper by taking File Stream as an example. It takes up data from the file and stores/processes it in the form of a byte. Now, the question is, how do we humans understand it?

You must understand that all the mentioned streams directly interact with the respective items which they are specifically designed for. To make it human understandable Stream Readers and Writers are used.

Stream Reader/Writers are helper classes used for reading/writing a string to a stream. It does this by converting characters (human understandable letters) to bytes or bytes to characters. They can be used to do the read/write operation in multiple Streams too.

Implementation of Streams

We will first implement the process of reading and writing data from a file using FileStreams. We will also implement the same using the StreamReader/Writer just to understand its significance.

Implementation using FileStreams

static void Main(string[] args)
        {
            var fileStreamWrite = new FileStream(@"D:\PARTECH\Textfile.txt",
                     FileMode.Create, FileAccess.Write, FileShare.None);

            var text = "This is a random text to be stored in a text file using FileStream class.";

            byte[] writeArr = Encoding.UTF8.GetBytes(text);

            fileStreamWrite.Write(writeArr, 0, text.Length);

            fileStreamWrite.Close();

            var fileStreamRead = new FileStream(@"D:\PARTECH\Textfile.txt",
                           FileMode.Open, FileAccess.Read, FileShare.Read);

            byte[] readArr = new byte[text.Length];
            int count;

            while ((count = fileStreamRead.Read(readArr, 0, readArr.Length)) > 0)
            {
                Console.WriteLine(Encoding.UTF8.GetString(readArr, 0, count));
            }

            fileStreamRead.Close();
            Console.ReadLine();
        }

Above is a sample code where:

  • The file has been created
  • Data has been written
  • Data has been read from it using FileStream

In the first line, an object for FileStream has been created by providing the full path of the text file, the mode of the file stream, access to the file, and share information. The object is stored in the variable fileStreamWrite.

In the next line, text that needs to be written in the file is stored in a string variable. The text that needs to be written in the file is converted to byte array data.

And finally, the byte array data is written to the file using the fileStreamWriter object. The connectivity between the object and the file is closed. At this point, the file is created, and the data is also imposed into the file.

To create the data from the file, the same FileStream is used by changing its mode to Read, and the new object is stored in fileStreamRead.

And the data is read from the code in the form of a byte array which is then converted to string data.

The below output gets displayed on executing the above code.

Implementation using StreamReader and Writer

Now, let us achieve the same using the StreamReader and Writer options.

namespace PARTECH_Streams
{
    internal class Program
    {
        static void Main(string[] args)
        {
            WriteData();
            ReadData();
            Console.ReadLine();
        }

        private static void WriteData()
        {
            using var streamWriter = new StreamWriter(@"D:\PARTECH\UsingStreamWriter.txt");
            streamWriter.WriteLine("This data is generated using the StreamWriter code and read using StreamReader");
            streamWriter.Close();
        }

        private static void ReadData()
        {
            using var streamReader = new StreamReader(@"D:\PARTECH\UsingStreamWriter.txt");
            Console.WriteLine(streamReader.ReadToEnd());
        }
    }
}

Here, we have created two methods WriteData and ReadData. In the WriteData method, we are using StreamWriter to create a new file (we have the option to either append on an existing file or replace content on an existing file. We can also specify the encoding that needs to be present in the document).

We then create an object for the streamwriter (it is an unmanaged code, so the ‘using’ keyword is used for IDisposable). Then we append data to the file in the next line, close the file and release the object.

In the ReadData method, we create an object for StreamReader(again, an unmanaged code). Then we read all the data from the document and write it in the console window.

On running the above code, the below output gets generated -

So, when we use StreamReader and Writer, we avoid the byte conversion, which we usually do when we use FileStream. Similarly, we can read contents from memorystream and other streams using StreamReader and Writer. Below is a sample code for the same.

            using var memoryStream = new MemoryStream(fileContents);
            Console.WriteLine("Data written in memory Stream");
            memoryStream.ToArray().ToList().ForEach(x => Console.WriteLine(x));
            using var fromMemoryStream = new StreamReader(memoryStream);
            Console.WriteLine(fromMemoryStream.ReadToEnd());

Conclusion

And that’s pretty much everything about Streams in C#. As you can see, Streams are one of the important concepts of C# that have helped thousands of developers to access and store data from multiple sources. So go ahead and use it in your next application.

Nieuwste