Monday, 17 September 2018

Understanding Streams (in .NET) #2

In Part 1 we looked at streams from a conceptual point of view. We learnt that streams are an abstraction over moving data from point A to point B. A very simple example of reading from a stream can be used to demonstrate this:

static void Main(string[] args)
{
using (Stream stream = GetStream())
{
int byteRead;
while ((byteRead = stream.ReadByte()) != -1)
{
Console.WriteLine(byteRead);
}
}
}
view raw streams.cs hosted with ❤ by GitHub
The GetStream() method returns a stream object from which we can read bytes until we are told there are no more bytes to read, which is indicated by -1 being returned. The stream abstraction is already working for us here as we've no idea - and potentially don't care - about where the data is coming from: we can simply keep asking for data until we're told there's no more data to be had.

To peek behind the curtain a little here is the GetStream() method:

private static Stream GetStream()
{
byte[] bytes = Encoding.ASCII.GetBytes("Hello, World!");
return new MemoryStream(bytes);
}
view raw memorystream.cs hosted with ❤ by GitHub
All I'm doing here is converting a string into an byte array where each byte is the ASCII representation of a character in the string. I then create a new MemoryStream object passing the byte array in to the constructor. Through the power of inheritance and the Liskov substitution principle we can treat the MemoryStream as it's parent Stream object.
On its own this doesn't seem terribly useful. But the data in the Stream doesn't have to be from an in-memory source. I could change the GetStream() method to the following and still read from it in the same way, even though the data now exists in a file:

private static FileStream GetStream()
{
FileStream fileStream = File.Open(@"C:\HelloWorld.txt", FileMode.Open);
return fileStream;
}
view raw filestream.cs hosted with ❤ by GitHub
I could even be reading from a stream whose bytes come over the internet:

private static Stream GetStream()
{
var webRequest = WebRequest.Create("http://www.google.co.uk");
var webResponse = webRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
return responseStream;
}
view raw webstream.cs hosted with ❤ by GitHub
These examples are a little contrived and not awfully useful as all I do with the byte I've read is write it out to the console and move onto the next one. That being said, bytes are the essential nature of all data, so we have an solid starting point to do more interesting things...

No comments:

Post a Comment