For many applications, data is held in memory and accessed as though it were a three-dimensional solid; when you need to access a variable or an object, use its name, and, presto, it is available to you. When you want to move your data into or out of a file, across the network, or over the Internet, however, your data must be streamed. In a stream, data flows much like bubbles in a stream of water.
Typically, the endpoint of a stream is a backing store. The backing store provides a source for the stream, like a lake provides a source for a river. Typically, the backing store is a file, but it is also possible for the backing store to be a network or web connection.
Files and directories are abstracted by classes in the .NET Framework. These classes provide methods and properties for creating, naming, manipulating, and deleting files and directories on your disk.
The .NET Framework provides buffered and unbuffered streams, as well as classes for asynchronous I/O. With asynchronous I/O, you can instruct the .NET classes to read your file; while they are busy getting the bits off the disk, your program can be working on other tasks. The asynchronous I/O tasks notify you when their work is done. The asynchronous classes are sufficiently powerful and robust that you might be able to avoid creating threads explicitly (see Chapter 21).
Streaming into and out of files is no different from streaming across the network, and the second part of this chapter will describe ...