Thursday, May 20, 2021

Streams in C#

Stream class in C#

Before understanding the concept of Stream, we should have clear idea of a computer file. A computer file can be defined as a computer resource which stores the data in non-volatile form. According to https://www.definitions.net/definition/file, 

"A computer file is a resource for storing information, which is available to a computer program and is usually based on some kind of durable storage. A file is durable in the sense that it remains available for programs to use after the current program has finished. Computer files can be considered as the modern counterpart of paper documents which traditionally are kept in offices' and libraries' files, and this is the source of the term. A group of files used by the same program can be packed into one archive file."

Thus, data on hard-disk drive and other non-volatile data storage media are in form of files. When data is read from the file or data is written into the file, data transmission is called stream i.e. flow of bytes. The files stored on physical disk has a logical system which is known as file system to represent logically grouped data or files. File handling is all about data storage on disk and retrieval of data from the disk. The file handling can be programmatically done in C#.

When file is opened for reading or writing, it is called stream. Opening file means creating stream i.e. flow of data.

Stream means flow of bytes. When file is opened for reading, Input stream is created and when file is opened for writing, Output stream is created. In short, Input stream => Read from file and Output stream => Write into file.

If file is water tank, then stream is flow of water from the tank.

The C# System.IO namespace provides classes to deal with input and output operations on files.

The classes in the System.IO namespaces such as BinaryReader, BinaryWriter, StreamReader, StreamWriter, StringReader, StringWriter, FileStream, FileInfo, DirectoryInfo etc, are used for file handling.

The System.IO.Stream is an abstract class which provides a generic view of a sequence of bytes. The class provides a number of methods to read or write the bytes. The classes that require reading bytes from a source or writing bytes to a destination must implement the Sstem.IO.Stream class. The following classes inherit System.IO.Stream class to provide the functionality to transfer bytes from a particular source:

FileStream: FileStream can read bytes from a file, whether it is a .txt, .exe, .jpg, or any other file. FileStream can write bytes to a file also. FileStream inherits the Stream class.

MemoryStream: MemoryStream can read bytes from memory or can write bytes to the memory. MemoryStream inherits the Stream class.

BufferedStream: BufferedStream can read bytes from streams and can write bytes as well. The buffering improves the read and write operations.

NetworkStream: NetworkStream can read bytes from a network socket and it can write bytes to the network socket also. A network socket is a software structure within a network node of a computer network that serves as an endpoint for sending and receiving data across the network. The structure and properties of a socket are defined by an application programming interface (API) for the networking architecture. Sockets are created only during the lifetime of a process of an application running in the node. The term network socket is most commonly used in the context of the Internet Protocol Suite, and is therefore often also referred to as Internet socket. https://en.wikipedia.org/wiki/Network_socket

PipeStream: PipeStream exposes a Stream object around a pipe, which supports both anonymous and named pipes. PipeStream reads or writes bytes from different processes. According to https://www.techopedia.com/definition/3410/pipe, "A pipe is a method used to pass information from one program process to another. Unlike other types of interprocess communication, a pipe only offers one-way communication by passing a parameter or output from one process to another. The information that is passed through the pipe is held by the system until it can be read by the receiving process." Also, Read Microsoft Doc, https://docs.microsoft.com/en-us/dotnet/standard/io/pipe-operations 

Anonymous pipes provide interprocess communication on a local computer. Anonymous pipes require less overhead than named pipes but offer limited services. Anonymous pipes are one-way and cannot be used over a network. They support only a single server instance. Anonymous pipes are useful for communication between threads, or between parent and child processes where the pipe handles can be easily passed to the child process when it is created.

CryptoStream: CryptoStream defines a stream for linking data streams to  cryptographic transformations. The bytes are encrypted from a stream and the bytes can be decrypted as well. For example, a string can be converted into a stream of bytes. The streams are then encrypted i.e. transformed into cryptic bytes. More at Microsoft Doc

There are two types of Reader and Writer in C# to read and write. The StreamReader and StreamWriter classes are character reader and character writer respectively. Similarly, BinaryReader and BinaryWriter classes are byte reader and byte writer respectively.

FileStream class reads bytes from a physical file and these bytes are converted into strings by StreamReader. Similarly, StreamWriter takes a string and convert them into stream of bytes and then FileStream class writes bytes to a physical file.

TextReader: It is an abstract class which represents a reader that can read a sequential series of characters.

StringReader: It implements a TextReader class and reads from a string.

StreamReader: It implements a TextReader class and reads characters from a byte stream in a particular encoding. StreamReader is designed for character input in a particular encoding, whereas the Stream class is designed for byte input and output. We should use StreamReader for reading lines of information from a standard text file.

Analogy: Just as a river is stream of water, remember that Stream means the stream of bytes. Stream provides a generic view of a sequence of bytes. This is an abstract class. Now, the bytes can be either consumed(by converting bytes into characters) or can be produced(by converting characters into bytes). Read implies the consumption of bytes and Write implies the production of bytes. (Read==Input, Write==Output) The consumption of bytes means converting bytes into characters and the production of bytes means converting characters into bytes.

According to Microsoft site, Streams involve three fundamental operations:
  • You can read from streams. Reading is the transfer of data from a stream into a data structure, such as an array of bytes.
  • You can write to streams. Writing is the transfer of data from a data structure into a stream.
  • Streams can support seeking. Seeking refers to querying and modifying the current position within a stream. Seek capability depends on the kind of backing store a stream has. For example, network streams have no unified concept of a current position, and therefore typically do not support seeking.
StreamReader class reads streams i.e. it converts bytes into characters. Note that each character represents the encoded bytes.
StreamWriter class writes streams i.e. it converts characters into bytes. Note that array of characters can be converted into string. So, the StreamWriter class converts strings into bytes.

BinaryReader and BinaryWriter classes are byte reader and byte writer respectively.
The BinaryReader class provides methods that simplify reading primitive data types from a stream. For example, you can use the ReadBoolean method to read the next byte as a Boolean value and advance the current position in the stream by one byte. The class includes read methods that support different data types. If you do not specify an encoding type, UTF-8 is used.

FileStream class reads bytes from a physical file and these bytes are converted into strings by StreamReader. Similarly, StreamWriter takes a string and convert them into stream of bytes and then FileStream class writes bytes to a physical file.

Steps to Read a file.
  1. Create an instance of FileInfo.
  2. The FileInfo instance method Open returns an object of type FileStream.
  3. This FileStream object will be consumed by StreamReader constructor as input parameter.
  4. The instance of StreamReader provides different methods such as ReadToEnd() to read the data in different ways.
  5. After reading the file, the FileStream and StreamReader objects should be closed.
Next,


No comments:

Post a Comment

Hot Topics