1.03k likes | 1.17k Views
Network Programming. Chapter 2 Streams in .NET. Basic Outline. Streams in .NET Stream Manipulation Serialisation. Introduction. A stream is an abstract representation of a sequence of bytes (e.g. file, I/O device or TCP/IP socket)
E N D
Network Programming Chapter 2 Streams in .NET
Basic Outline • Streams in .NET • Stream Manipulation • Serialisation
Introduction • A stream is an abstract representation of a sequence of bytes (e.g. file, I/O device or TCP/IP socket) • Abstraction allows us to access different devices in the same manner (like with inheritance)
Streams in .NET • Stream class • Abstract class • Perform binary I/O operations • TextReader & TextWriter classes • BinaryReader & BinaryWriter classes
Streams in .NET • Synchronous and Asynchronous I/O • Stream class provides for both synchronous & asynchronous • Stream Class • FileStream Class • Reading and Writing with the FileStream Class • BufferedStream Class • MemoryStream Class • NetworkStream Class • CryptoStream Class
Synchronous I/O • Default “setting” • Simplest method • Blocks processing until operation is complete (disadvantage) • Not suitable for operations over a network • Not good choice for large files over low bandwidth • Can simulate asynchronous I/O by threading
Asynchronous I/O • Allows other processing • Operating system notifies caller when I/O processing is done • Needs separate notification mechanism • Useful when application needs to process other tasks while doing I/O • A separate thread is created for each I/O thread (higher O/S overhead)
Streams in .NET • Synchronous and Asynchronous I/O • Stream Class • FileStream Class • Reading and Writing with the FileStream Class • BufferedStream Class • MemoryStream Class • NetworkStream Class • CryptoStream Class
Stream Class System.Security.Cryptography System.Security.Cryptography.CryptoStream
Stream Class • Base class = System.IO • Stream is base class for all other stream classes
Synchronous Methods for Reading from and Writing to a Stream
Asynchronous Methods for Reading from and Writing to a Stream
Streams in .NET • Synchronous and Asynchronous I/O • Stream Class • FileStream Class • Reading and Writing with the FileStream Class • BufferedStream Class • MemoryStream Class • NetworkStream Class • CryptoStream Class
FileStream Class • One of the most widely used of the Stream-derived classes • Handles files and standard input and output devices • Several ways to create a FileStream object
Creating a FileStream Instance with a File Path • Specify a path to a file • Default buffer is 8192 bytes • Buffer size may be changed in constructor • Methods of creating a FileStream • Specifying the File Path and Mode • Specifying File Access • Specifying Sharing Permissions • Specifying Buffer Size • Specifying Synchronous or Asynchronous State
FileMode Syntax • To create a FileStream object that creates a new file called c:\Networking\MyStream.txt, you would use the following //Using file path and file mode FileStream inF = new FileStream(“C:\\Networking\\MyStream.txt”, FileMode.CreateNew);
FileAccess Syntax • You can use the CanRead and CanWrite properties to check the FileAccess permission given to the file • To create a new file called c:\Networking\MyStream.txt with write-only access //Using file path, file mode and file access FileStream inF = new FileStream(“C:\\Networking\\MyStream.txt”, FileMode.CreateNew, FileAccess.Write);
FileShare Syntax • Create a FileStream instance using the FileMode, FileAccess and FileShare properties //Using file path, file mode, file access and sharing permission //Open file for writing, other processes will get read-only access FileStream inF = new FileStream (“C:\\Networking\\MyStream.txt”, FileMode.Open, FileAccess.Write, FileShare.Read);
Specifying Buffer Size • You can also create a FileStream instance by specifying the size of the buffer in addition to the parameters discussed previously. Here we set the size of the buffer to 1000 bytes: //using path, mode, access, sharing permission and buffer size FileStream inF = new FileStream(“C:\\Networking\\MyStream.txt”, FileMode.Open, FileAccess.Write, FileShare.Read, 1000); • If the buffer size specified is between 0 and 8 bytes, the actually buffer is set to 8 bytes
Specifying Synchronous or Asynchronous State //Using path, mode, access, sharing permission, buffer size and specifying asynchronous operations FileStream outF = new FileStream(“C:\\Networking\\MyStream.txt”, FileMode.Open, FileAccess.Write, FileShare.Read, 1000, true);
File Handle • A file handle is a unique identifier that the operating system assigns to a file when the file is opened or created • A file handle is represented using the IntPrt structure, which represents an integer of platform-specific length. • Using the file handle, you may specify several properties of the stream • //Create FileStream Instance • FileStream inF = new FileStream( “C:\Neworking\\MyStream.txt”, FileMode.Open); • Get the file Handle • InterPtr fHanld = infHandle
Streams in .NET • Synchronous and Asynchronous I/O • Stream class provides for both synchronous & asynchronous • Stream Class • FileStream Class • Reading and Writing with the FileStream Class • BufferedStream Class • MemoryStream Class • NetworkStream Class • CryptoStream Class
Reading & Writing • Synchronous I/O • Stream class • Asynchronous I/O
Synchronous I/O • Stream class • Read method • Write method • Example • Performs synchronous I/O operations • Seek method sets the position within the stream • Need System.IO namespace • Need System.Text (convert strings to byte arrays)
Synchronous I/O using System; using System.Collections.Generic; using System.Text; using System.IO; namespace SyncIO { class Program { Note: additional namespace(s)
Synchronous I/O static void Main(string[] args) { //Create FileStream instance FileStream synF = new FileStream("SyncDemo.txt", FileMode.OpenOrCreate); //this will open our file if it exists; otherwise a new file is created.
Synchronous I/O //A character is converted to a byte and then written in a file using the WriteByte method //After the byte is written, the file position is automatically incremented by 1. Console.WriteLine("--Writebyte Method demo--"); synF.WriteByte(Convert.ToByte('A'));
Synchronous I/O //Converting a string to a byte array (with the GetBytes method of the Encoding class in System.Text //Write takes three parameters: // * the byte array to write // * the position or offset in the array from where to start writing // * the length of data to be written Console.WriteLine("--Write method demo--"); byte[] writeBytes = Encoding.ASCII.GetBytes(" is the first character."); synF.Write(writeBytes, 0, writeBytes.Length);
Synchronous I/O //Reading the data from the file //When reading or writing on a FileStream, the current position(or pointer)of the file automatically //increases by the number of bytes read or written. //set pointer at origin (start of file or start of stream) synF.Seek(0, SeekOrigin.Begin); //Now we can read. We'll read a single byte with the ReadByte method first. //A byte is read from the stream (with the position automatically increased by 1) and converted by to char. Console.WriteLine("--Readbyte Method demo--"); //Read byte and display Console.WriteLine("First character is -> " + Convert.ToChar(synF.ReadByte()));
Synchronous I/O //Now we read the remainder of the file with the Read method. //This method takes 3 parameters: // * A byte array that will store the data read // * the position or offset in the array from where to start reading // * the number of bytes to read //Because we want to read all of the remaining bytes in the file, we want to read in synF.Length - 1 bytes //Use of Read method Console.WriteLine("--Read Method demo--"); //Allocate buffer byte[] readBuf = new byte[synF.Length - 1]; //Read file synF.Read(readBuf, 0, Convert.ToInt32(synF.Length - 1));
Synchronous I/O //The byte array is then converted to string using the GetString method of the Encoding Class //Display contents Console.WriteLine("The rest of the file is: " + Encoding.ASCII.GetString(readBuf)); //close the file synF.Close(); Console.WriteLine("Press a key to continue."); Console.ReadLine(); } } }
Asynchronous I/O • FileStream opens asynchronously when you pass true to the useAsync flag • A special call-back mechanism is needed to implement asynchronous I/O, and an AsyncCallback delegate provides a way for client applications to implement this call-back mechanism. • This call-back delegate is supplied to the BeginRead or BeginWrite method
Asynchronous I/O using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; namespace AsyncDemo { class Program { //Stream object for reading static FileStream fileStrm; //Buffer to read static byte[] readBuff;
Asynchronous I/O //We declare an AsyncCallback delegate field for the callback function //AsyncCallback delegate static AsyncCallback Callback; //In the Main method, we initialize our callback delegate to point to the Callback function method //This is the method that will be called when the end of the aynchronous read operation is signalled
Asynchronous I/O static void Main(string[] args) { Callback = new AsyncCallback(CallBackFunction); //now we can initialise our FileStream object, specifying asynchronous operations fileStrm = new FileStream("Test.txt", FileMode.Open, FileAccess.Read, FileShare.Read, 64, true); readBuff = new byte[fileStrm.Length]; //we can use the BeginRead method to initiate asynchronous read opeations on the stream. //The callback delegate is passed to the BeginRead method as its second-to-last parameter. //Call async read fileStrm.BeginRead(readBuff, 0, readBuff.Length, Callback, null);
Asynchronous I/O //Data will be read from FileStream while we continue with other activities. //Here we simply give the appearance of doing some other work by looping and every so often putting the main thread to sleep //Once the loop has finished, the FileStream object is closed. //Simulation of main execution for (long i = 0; i < 5000; i++) { if (i % 1000 == 0) { Console.WriteLine("Executing in Main - " + i.ToString()); Thread.Sleep(10) } //end of if } //end of for long fileStrm.Close(); Console.WriteLine("Press a key to continue."); Console.ReadLine(); } //end of Main
Asynchronous I/O static void CallBackFunction(IAsyncResult asyncResult) { //Gets called when read operation has completed int readB = fileStrm.EndRead(asyncResult); if (readB > 0) { Console.WriteLine(Encoding.ASCII.GetString(readBuff, 0, readB)) } //end of if } //end of CallBackFunction } }
Streams in .NET • Synchronous and Asynchronous I/O • Stream class provides for both synchronous & asynchronous • Stream Class • FileStream Class • Reading and Writing with the FileStream Class • BufferedStream Class • MemoryStream Class • NetworkStream Class • CryptoStream Class
Buffered Stream Class • A buffer is a reserved area of memory used for storing temporary data. • Its main purpose is to improve I/O performance, and it’s often used to synchronise data transfer between devices of different speeds. Many online media applications use buffers as intermediate storage. • BufferedStream Class • Stream object • Generally used with .NetworkStream to store data in memory • FileStream Class has its own internal buffer • MemoryStream Class does not require buffering
Buffered Stream Class using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; namespace BufferedStreamDemo { class Program { static void Main(string[] args) { FileStream fStr = new FileStream("BufferDemo.txt", FileMode.OpenOrCreate); byte[] writeBytes = Encoding.ASCII.GetBytes("The difference between genius and stupidity is that genius has its limits."); fStr.Write(writeBytes, 0, writeBytes.Length); Console.WriteLine("Message written"); fStr.Seek(0, SeekOrigin.Begin); readBufStream(fStr); Console.WriteLine("Press a key to continue"); Console.ReadLine(); }
Buffered Stream Class //Takes a stream object parameters, wraps it in a buffered stream object and performs a read operaton //Reading Buffered Stream public static void readBufStream(Stream st) { //Compose BufferedStream BufferedStream bf = new BufferedStream(st); byte[] inData = new Byte[st.Length]; //Read and display buffered data bf.Read(inData, 0, Convert.ToInt32(st.Length)); Console.WriteLine(Encoding.ASCII.GetString(inData)); } } }
Memory Stream Class • Situation where application needs data frequently (e.g. lookup table) • Storing data in file • Cause delays • Reduce performance of application • Use MemoryStream Class for cases where data needs to be stored in memory • MemoryStream Class is used for fast, temporary storage
Memory Stream Class using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; namespace MemoryStreamDemo { class Program { static void Main(string[] args) { //Create empty Memory stream MemoryStream ms = new MemoryStream(); byte[] memData = Encoding.ASCII.GetBytes("This will go in Memory!"); //Write data ms.Write(memData, 0, memData.Length);
Memory Stream Class //Set pointer at origin ms.Position = 0; byte[] inData = new byte[100]; //Read memory ms.Read(inData, 0, 100); Console.WriteLine(Encoding.ASCII.GetString(inData)); Stream str = new FileStream("MemOutput.txt", FileMode.OpenOrCreate, FileAccess.Write); ms.WriteTo(str); str.Close(); } } }