For many applications, data is held in memory and accessed as if it were a three-dimensional solid; when you need to access a variable or an object, use its nameand, 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, packets of data flow one after the other, much like bubbles in a stream of water.
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 both 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 20).
Streaming into and out of files is no different than streaming across the network, and the second part of this chapter will describe streaming using both TCP/IP and web protocols.
To create a stream of data, your object must be serialized, or written to the stream as a series of bits. You have already encountered serialization in Chapter 19. The .NET Framework provides extensive support for serialization, and the final part of this chapter walks you through the details of taking control of the serialization of your object.