Input/Output

The BCL provides a streams-based I/O framework that can handle a wide range of stream and backing store types. This support for streams also infuses the rest of the BCL, with the pattern repeating in non-I/O areas such as cryptography, HTTP support, and more.

This section describes the core stream types and provides examples. The types mentioned in this section all exist in the System.I/O namespace.

Streams and Backing Stores

A stream represents the flow of data coming in and out of a backing store. A backing store represents the endpoint of a stream. Although a backing store is often a file or network connection, in reality it can represent any medium capable of reading or writing raw data.

A simple example would be to use a stream to read and write to a file on disk. However, streams and backing stores are not limited to disk and network I/O. A more sophisticated example would be to use the cryptography support in the BCL to encrypt or decrypt a stream of bytes as they move around in memory.

Abstract Stream class

Stream is an abstract class that defines operations for reading and writing a stream of raw typeless data as bytes. Once a stream has been opened, it stays open and can be read from or written to until the stream is flushed and closed. Flushing a stream updates the writes made to the stream; closing a stream first flushes the stream, then closes the stream.

Stream has the methods CanRead , CanWrite , and CanSeek , for streams that support only sequential access. If a stream supports random access, the SetPosition method can move to a linear position on that stream.

The Stream class provides synchronous and asynchronous read and write operations. By default, an asynchronous method calls the stream’s corresponding synchronous method by wrapping the synchronous method in a delegate type and starting a new thread. Similarly, by default, a synchronous method calls the stream’s corresponding asynchronous method and waits until the thread has completed its operation. Classes that derive from Stream must override either the synchronous or asynchronous methods but may override both sets of methods if the need arises.

Concrete Stream-derived classes

The BCL includes a number of different concrete implementations of the abstract base class Stream. Each implementation represents a different storage medium and allows a raw stream of bytes to be read from and written to the backing store.

Examples of this include the FileStream class (which reads and writes bytes to and from a file) and the NetworkStream class (which sends and receives bytes over the network).

In addition, a stream may act as the frontend to another stream, performing additional processing on the underlying stream as needed. Examples of this include stream encryption/decryption and stream buffering.

Here is an example that creates a text file on disk and uses the abstract File type to write data to it:

using System.IO;
class Test {
  static void Main( ) {
    Stream s = new FileStream("foo.txt", Filemode.Create);
    s.WriteByte("67");
    s.WriteByte("35");
    s.Close( );
  }
}

Encapsulating raw streams

The Stream class defines operations for reading and writing raw typeless data, in the form of bytes. Typically, however, you need to work with a stream of characters, not a stream of bytes. To solve this problem, the BCL provides the abstract base classes TextReader and TextWriter, which define a contract to read and write a stream of characters, as well as a set of concrete implementations.

Abstract TextReader/TextWriter classes

TextReader and TextWriter are abstract base classes that define operations for reading and writing a stream of characters. The most fundamental operations of the TextReader and TextWriter classes are the methods that read and write a single character to or from a stream.

The TextReader class provides default implementations for methods that read in an array of characters or a string representing a line of characters. The TextWriter class provides default implementations for methods that write an array of characters, as well as methods that convert common types (optionally with formatting options) to a sequence of characters.

The BCL includes a number of different concrete implementations of the abstract base classes TextReader and TextWriter. Some of the most prominent include StreamReader and StreamWriter, and StringReader and StringWriter.

StreamReader and StreamWriter classes

StreamReader and StreamWriter are concrete classes that derive from TextReader and TextWriter, respectively, and operate on a Stream (passed as a constructor parameter).

These classes allow you to combine a Stream (which can have a backing store but only knows about raw data) with a TextReader/TextWriter (which knows about character data, but doesn’t have a backing store).

In addition, StreamReader and StreamWriter can perform special translations between characters and raw bytes. Such translations include translating Unicode characters to ANSI characters to either big- or little-endian format.

Here is an example that uses a StreamWriter wrapped around a FileStream class to write to a file:

using System.Text;
using System.IO;
class Test {
  static void Main( ) {
    Stream fs = new FileStream ("foo.txt", FileMode.Create);
    StreamWriter sw = new StreamWriter(fs, Encoding.ASCII);
    sw.Write("Hello!");
    sw.Close( );
  }
}

StringReader and StringWriter classes

StringReader and StringWriter are concrete classes that derive from TextReader and TextWriter, respectively, and operate on a string (passed as a constructor parameter).

The StringReader class can be thought of as the simplest possible read-only backing store, because it simply performs read operations on that string. The StringWriter class can be thought of as the simplest possible write-only backing store, because it simply performs write operations on that StringBuilder.

Here is an example that uses a StringWriter wrapped around an underlying StringBuilder backing store to write to a string:

using System;
using System.IO;
using System.Text;
class Test {
  static void Main( ) {
    StringBuilder sb = new StringBuilder( );
    StringWriter sw = new StringWriter(sb);
    WriteHello(sw);
    Console.WriteLine(sb);
  }
  static void WriteHello(TextWriter tw) {
    tw.Write("Hello, String I/O!");
  }
}

Directories and Files

The File and Directory classes encapsulate the operations typically associated with file I/O, such as copying, moving, deleting, renaming, and enumerating files and directories.

The actual manipulation of the contents of a file is done with a FileStream. The File class has methods that return a FileStream, though you may directly instantiate a FileStream.

In this example, you read in and print out the contents of a text file specified on the command line:

using System;
using System.IO;
class Test {
   static void Main(string[] args) {
      Stream s = File.OpenRead(args[0]);
      StreamReader sr = new StreamReader(s);
      Console.WriteLine(sr.ReadLine( ));
      sr.Close( );
   }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.164.143