| What we have in this page?
You’ve already used the Console class to perform I/O to and from the console. This module will introduce you to the System::IO namespace, which contains the classes, structures, and enumerations that implement the Microsoft .NET I/O model. If you know anything about the Java I/O mechanism as implemented in the java.io package, you’ll find it easy to start working with .NET I/O because the two have many similarities.
The System::IO Namespace
The System::IO namespace contains all the classes that are used for binary and text I/O, as well as classes and types that provide basic file and directory support. The following table lists the main classes, structure, delegates and enumeration in the namespace. |
| Class | Description |
| Symbol | |
| BinaryReader | Reads primitive data types as binary values in a specific encoding. |
| BinaryWriter | Writes primitive types in binary to a stream and supports writing strings in a specific encoding. |
| BufferedStream | Adds a buffering layer to read and write operations on another stream. This class cannot be inherited. |
| Directory | Exposes static methods for creating, moving, and enumerating through directories and subdirectories. This class cannot be inherited. |
| DirectoryInfo | Exposes instance methods for creating, moving, and enumerating through directories and subdirectories. This class cannot be inherited. |
| DirectoryNotFoundException | The exception that is thrown when part of a file or directory cannot be found. |
| DriveInfo | Provides access to information on a drive. |
| DriveNotFoundException | The exception that is thrown when trying to access a drive or share that is not available. |
| EndOfStreamException | The exception that is thrown when reading is attempted past the end of a stream. |
| ErrorEventArgs | Provides data for the Error event. |
| File | Provides static methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects. |
| FileInfo | Provides instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects. This class cannot be inherited. |
| FileLoadException | The exception that is thrown when a managed assembly is found but cannot be loaded. |
| FileNotFoundException | The exception that is thrown when an attempt to access a file that does not exist on disk fails. |
| FileStream | Exposes a Stream around a file, supporting both synchronous and asynchronous read and write operations. |
| FileSystemEventArgs | Provides data for the directory events: Changed, Created, Deleted. |
| FileSystemInfo | Provides the base class for both FileInfo and DirectoryInfo objects. |
| FileSystemWatcher | Listens to the file system change notifications and raises events when a directory, or file in a directory, changes. |
| InternalBufferOverflowException | The exception thrown when the internal buffer overflows. |
| InvalidDataException | The exception that is thrown when a data stream is in an invalid format. |
| IODescriptionAttribute | Sets the description visual designers can display when referencing an event, extender, or property. |
| IOException | The exception that is thrown when an I/O error occurs. |
| MemoryStream | Creates a stream whose backing store is memory. |
| Path | Performs operations on String instances that contain file or directory path information. These operations are performed in a cross-platform manner. |
| PathTooLongException | The exception that is thrown when a pathname or filename is longer than the system-defined maximum length. |
| RenamedEventArgs | Provides data for the Renamed event. |
| Stream | Provides a generic view of a sequence of bytes. |
| StreamReader | Implements a TextReader that reads characters from a byte stream in a particular encoding. |
| StreamWriter | Implements a TextWriter for writing characters to a stream in a particular encoding. |
| StringReader | Implements a TextReader that reads from a string. |
| StringWriter | Implements a TextWriter for writing information to a string. The information is stored in an underlying StringBuilder. |
| TextReader | Represents a reader that can read a sequential series of characters. |
| TextWriter | Represents a writer that can write a sequential series of characters. This class is abstract. |
| UnmanagedMemoryStream | Provides access to unmanaged blocks of memory from managed code. |
|
Table 1 | |
| Structure | Description |
| Symbol | |
| WaitForChangedResult | Contains information on the change that occurred. |
|
Table 1.1 | |
| Delegate | Description |
| Symbol | |
| ErrorEventHandler | Represents the method that will handle the Error event of a FileSystemWatcher object. |
| FileSystemEventHandler | Represents the method that will handle the Changed, Created, or Deleted event of a FileSystemWatcher class. |
| RenamedEventHandler | Represents the method that will handle the Renamed event of a FileSystemWatcher class. |
|
Table 2 | |
| Enumeration | Description |
| Symbol | |
| DriveType | Defines constants for drive types, including CDRom, Fixed, Network, NoRootDirectory, Ram, Removable, and Unknown. |
| FileAccess | Defines constants for read, write, or read/write access to a file. |
| FileAttributes | Provides attributes for files and directories. |
| FileMode | Specifies how the operating system should open a file. |
| FileOptions | Represents additional options for creating a FileStream object. |
| FileShare | Contains constants for controlling the kind of access other FileStream objects can have to the same file. |
| NotifyFilters | Specifies changes to watch for in a file or folder. |
| SearchOption | Specifies whether to search the current directory, or the current directory and all subdirectories. |
| SeekOrigin | Provides the fields that represent reference points in streams for seeking. |
| WatcherChangeTypes | Changes that might occur to a file or directory. |
|
Table 3 | |
The I/O oriented classes in System::IO can be divided into the following three groups:
The Stream classes, which are designed for I/O of streams of bytes.
The BinaryReader and BinaryWriter classes, which are used to input and output .NET primitive types, such as Int32 and Double, in binary form.
The TextReader and TextWriter classes, which are used for character-mode I/O.
This module focuses on the latter two groups.
TextReader and TextWriter are the abstract base classes for a group of classes that are used to read and write characters. There are four classes in System::IO that derive from these two bases - StreamReader, StreamWriter, StringReader, and StringWriter - along with several other much more specialized writer classes in other namespaces.
The TextWriter class has a number of useful public and protected methods, as summarized in the following table.
| Public Methods | |
| Name | Description |
| Symbol | |
| Close | Closes the current writer and releases any system resources associated with the writer. |
| CreateObjRef | Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) |
| Dispose | Overloaded. Releases all resources used by the TextWriter object. |
| Equals | Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) |
| Flush | Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. |
| GetHashCode | Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.) |
| GetLifetimeService | Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) |
| GetType | Gets the Type of the current instance. (Inherited from Object.) |
| InitializeLifetimeService | Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) |
| ReferenceEquals | Determines whether the specified Object instances are the same instance. (Inherited from Object.) |
| Synchronized | Creates a thread-safe wrapper around the specified TextWriter. |
| ToString | Returns a String that represents the current Object. (Inherited from Object.) |
| Write | Overloaded. Writes the given data type to a text stream. |
| WriteLine | Overloaded. Writes some data as specified by the overloaded parameters, followed by a line terminator. |
|
Table 4 | |
| Protected Methods | |
| Name | Description |
| Symbol | |
| Dispose | Overloaded. Releases all resources used by the TextWriter object. |
| Finalize | Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) |
| MemberwiseClone | Overloaded. (Inherited from MarshalByRefObject.) |
|
Table 5 | |
As you might guess from the inclusion of the Write and WriteLine functions in the table, the Console class uses a TextWriter object to perform output. To show you how the I/O classes work together, let’s look at how you use the StreamWriter class. Before we start, though, it’s important that you understand how the .NET Framework implements I/O. Rather than create a number of classes that each perform an end-to-end I/O task, .NET implements a number of smaller general-purpose classes that you can plug together to get the effect you want. So .NET doesn’t have a “write characters to a file” class and a “write characters to the screen” class. Instead, it has a “write characters to a byte stream” class and a “read bytes from a stream and write them to a file” class. If you plug the output from the first class into the input of the second, you end up writing characters to a file.
This model is flexible because you can take binary or character data, convert it into bytes, and then pass the bytes to any of several classes to output them to files, memory, or a string. Data is transferred between the classes as streams of bytes, a method that provides a flexible base on which to build. The basic functionality for handling byte streams is provided by the Stream class, and you can build your own specialized I/O classes on top of Stream if you need to. With that information in mind, the following exercise will show you how to write character data to a text file using a TextWriter. Using the Plug and Play model for I/O that the .NET Framework uses, you need to create the following two objects:
A FileStream object that takes bytes as input and writes them to a file.
A StreamWriter object that takes text and converts it to a byte stream.