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.
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.
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.
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( ); } }
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.
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
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
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!"); } }
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( ); } }
18.217.164.143