File input-output
File input-output
Subjects:
-
Introduction. Streams. Readers and Writers.
-
System.IO namespace
-
FileInfo class
-
Working with the File type
-
The Directory(Info)
and File(Info) types
-
DriveInfo class type
-
The abstract Stream class
-
Working with FileStream
-
Working with StreamWriters and StreamReaders
-
Reading from a text file
-
Working with BinaryReader and BinaryWriter
Subjects:
-
Introduction. Streams. Readers and Writers.
-
System.IO namespace
-
FileInfo class
-
Working with the File type
-
The Directory(Info)
and File(Info) types
-
DriveInfo class type
-
The abstract Stream class
-
Working with FileStream
-
Working with StreamWriters and StreamReaders
-
Reading from a text file
Introduction.
Streams
Introduction.
Streams
File access refers to the storage and retrieval of data on the disk. The input-output (I/O) classes are defined in the System.IO namespace. The basic file I/O class is
FileStream.
C# uses a more intuitive approach, associating each file with an object of class
FileStream. The constructor for FileStream opens the file and manages the underlying handle. The methods of FileStream perform the file I/O. FileStream
isn’t the only class that can perform file I/O. However, it represents your good ol’ basic file that covers 90 percent of your file I/O needs.
The .NET classes used in C# include an abstract Stream base class and several subclasses, for working with files on the disk, over a network, or already sitting as chunks of data in memory. Some stream classes specialize in encrypting and decrypting data, some are provided to help speed up I/O operations that might be slow using one of the other streams, and you’re free to extend class Stream with your own subclass if you come up with a great idea for a new stream.
Readers and writers
Readers and writers
FileStream, the stream class you’ll probably use the most, is a basic class. Open a file, close a file, read a block of bytes, and write a block — that’s about all you have. But reading and writing files down at the byte level is a lot of work. Fortunately, the .NET class library introduces the notion of “readers” and “writers.” Objects of these types greatly simplify file I/O.
When you create a new reader (of one of several available types), you associate a stream object with it. It’s immaterial to the reader whether the stream connects to a file, a block of memory, a network location. The reader requests input from the stream, which gets it from — well, wherever. Using writers is quite similar, except that you’re sending output to the stream rather than asking for input. The stream sends it to a specified destination. Often that’s a file, but not always.
The System.IO namespace contains classes that wrap around FileStream (or other
streams) to give you easier access:
✦ TextReader/TextWriter: A pair of abstract classes for reading characters (text). These classes are the base for two flavors of subclasses:
StringReader/StringWriter and StreamReader/StreamWriter. Because
TextReader and TextWriter are abstract, you’ll use one of their subclass pairs,
Readers and writers
Readers and writers
✦ StreamReader/StreamWriter: A more sophisticated text reader and writer for the more discriminating palate — not to mention that they aren’t abstract, so you can even read and write with them. For example, StreamWriter has a WriteLine() method much like that in the Console class. StreamReader has a corresponding
ReadLine() method and a handy ReadToEnd() method that grabs the whole text file in one gulp, returning the characters read as a string — which you could then use with a
StringReader, a foreach loop, the String.Split() method, and so on. Check
out the various constructors for these classes in Help.
One nice thing about reader/writer classes such as StreamReader and
StreamWriter is that you can use them with any kind of stream. This makes reading from and writing to a MemoryStream no harder than reading from and writing to the kind
of FileStream.
The C# System.IO classes also support asynchronous I/O. Using asynchronous I/O, the
read() call returns immediately to allow the program to continue doing something else while the I/O request is completed in the background. The program can check a “done” flag at its leisure to decide when the I/O has completed.
StreamWriting
StreamWriting
Programs generate two kinds of output:
✦ Some programs write blocks of data as bytes in pure binary format. This type of output is useful for storing objects in an efficient way — for example, a file of Student objects that you need to persist (keep on disk in a permanent file).
A sophisticated example of binary I/O is the persistence of groups of objects that refer to each other (using the HAS_A relationship). Writing an object to disk involves writing identifying information (so its type can be reconstructed when you read the object back in), and then each of its data members, some of which may be references to connected objects, each with its own identifying information and data members. Persisting objects this way is called serialization. You can look it up in Help.
StreamWriting
StreamWriting
Human-readable data was formerly known as ASCII or, slightly later, ANSI, text. These two monikers refer to the standards organization that defined them. However, ANSI encoding doesn’t provide the alphabets east of Austria and west of Hawaii; it can handle only Roman letters, like those used in English. It has no characters for Russian, Hebrew, Arabic, Hindi, or any other language using a non-Roman alphabet, including Asian languages such as Chinese, Japanese, and Korean. The modern, more flexible Unicode file format is “backward-compatible” — including the familiar ANSI characters at the beginning of its character set, but still providing a large number of other alphabets, including everything you need for all the languages listed. Unicode comes in several variations, called
System.IO namespace
System.IO namespace
I/O Class Type Meaning in Life
BinaryReader, BinaryWriter
These types allow you to store and retrieve primitive data types (integers, Booleans, strings, and whatnot) as a binary value.
BufferedStream This type provides temporary storage for a stream of bytes that may be committed to storage at a later time.
Directory, DirectoryInfo
These types are used to manipulate a machine’s directory structure.
DriveInfo This type provides information regarding the drives used by a given machine. File, FileInfo These types are used to manipulate a machine’s set of files.
FileStream This type allows for random file access (e.g., seeking capabilities) with data represented as a stream of bytes.
FileSystemWatcher Allows you to monitor the modification of external files in a specified directory. MemoryStream This type provides random access to streamed data stored in memory.
Path This type performs operations on System.String types that contain file or directory path information in a platform-neutral manner.
StreamWriter, StreamReader
These types are used to store (and retrieve) textual information to (or from) a file. These types do not support random file access.
StringWriter, StringReader
FileInfo
class
FileInfo
class
The FileInfo class allows you to obtain details regarding existing files on your hard drive (time created, size, file attributes, and so forth) and aids in the creation, copying, moving, and destruction of files.
Member Meaning in Life
AppendText() Creates a StreamWriter type (described later) that appends text to a file CopyTo() Copies an existing file to a new file
Create() Creates a new file and returns a FileStream type to interact with the created file CreateText() Creates a StreamWriter type that writes a new text file
Delete() Deletes the file to which a FileInfo instance is bound Directory Gets an instance of the parent directory
DirectoryName Gets the full path to the parent directory Length Gets the size of the current file or directory
MoveTo() Moves a file to a new location, providing the option to specify a new file name Name Gets the name of the file
Open() Opens a file with various read/write and sharing privileges OpenRead() Creates a read-only FileStream
OpenText() Creates a StreamReader type (described later) that reads from an existing text file OpenWrite() Creates a write-only FileStream type
FileInfo.Create()
method
FileInfo.Create()
method
The first way you can create a file handle is to make use of the
FileInfo.Create()
method:
static void Main(string[] args) {
// Make a new file on the C drive.
FileInfo f = new FileInfo(@"C:\test.dat"); FileStream fs = f.Create();
// Use the FileStream object... // Close down file stream.
fs.Close(); }
The FileInfo.Create() method returns a FileStream type, which exposes synchronous and asynchronous write/read operations to/from the underlying file (more details in a moment).
static void Main(string[] args) {
// Defining a 'using scope' for file I/O types is ideal. FileInfo f = new FileInfo(@"C:\Test.dat");
using (FileStream fs = f.Create()) {
// Use the FileStream object... }
FileInfo.Open()
method
FileInfo.Open()
method
You can use the FileInfo.Open() method to open existing files as well as create new files with far more precision than FileInfo.Create(), given that Open() typically takes several parameters to qualify the overall structure of the file you are manipulating. Once the call to
Open() completes, you are returned a FileStream object.
static void Main(string[] args) {
// Make a new file via FileInfo.Open().
FileInfo f2 = new FileInfo(@"C:\test2.dat");
using(FileStream fs2 = f2.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
// Use the FileStream object... }
}
This version of the overloaded Open() method requires three parameters. The first parameter specifies the general flavor of the I/O request (e.g., make a new file, open an existing file, append to a file, etc.), which is specified using the FileMode enumeration:
public enum FileMode {
CreateNew, Create, Open, OpenOrCreate, Truncate, Append
FileInfo.Open()
method
FileInfo.Open()
method
Member Meaning in Life
CreateNew Informs the OS to make a new file. If it already exists, an IOException is thrown.
Create Informs the OS to make a new file. If it already exists, it will be overwritten.
Open Opens an existing file. If the file does not exist, a FileNotFoundException is thrown.
OpenOrCreate Opens the file if it exists; otherwise, a new file is created.
Truncate Opens a file and truncates the file to 0 bytes in size.
Append Opens a file, moves to the end of the file, and begins write operations (this flag can only be used with a write-only stream). If the file does not exist, a new file is created.
Members of the FileMode Enumeration
The second parameter, a value from the FileAccess enumeration, is used to determine the read/write behavior of the underlying stream:
public enum FileAccess {
Read, Write, ReadWrite }
Finally, you have the third parameter, FileShare, which specifies how the file is to be shared among other file handlers. Here are the core names:
public enum FileShare {
FileInfo.OpenRead()
and
FileInfo.OpenWrite()
methods
FileInfo.OpenRead()
and
FileInfo.OpenWrite()
methods
While the FileInfo.Open() method allows you to obtain a file handle in a very flexible manner, the FileInfo class also provides members named OpenRead() and OpenWrite(). As you might imagine, these methods return a properly configured read-only or write-only FileStream type, without the need to supply various enumeration values.
static void Main(string[] args) {
// Get a FileStream object with read-only permissions. FileInfo f3 = new FileInfo(@"C:\test3.dat");
using(FileStream readOnlyStream = f3.OpenRead()) {
// Use the FileStream object... }
// Now get a FileStream object with write-only permissions. FileInfo f4 = new FileInfo(@"C:\test4.dat");
using(FileStream writeOnlyStream = f4.OpenWrite()) {
// Use the FileStream object... }
}
Like FileInfo.Create() and FileInfo.Open(), OpenRead() and OpenWrite() return a
FileInfo.OpenText(), FileInfo.CreateText()
and
FileInfo.AppendText()
methods
FileInfo.OpenText(), FileInfo.CreateText()
and
FileInfo.AppendText()
methods
Another open-centric member of the FileInfo type is OpenText(). Unlike Create(),
Open(), OpenRead(), and OpenWrite(), the OpenText() method returns an instance of the
StreamReader type, rather than a FileStream type.
static void Main(string[] args) {
// Get a StreamReader object.
FileInfo f5 = new FileInfo(@"C:\boot.ini"); using(StreamReader sreader = f5.OpenText()) {
// Use the StreamReader object... }
}
The StreamReader type provides a way to read character data from the underlying file.
static void Main(string[] args) {
FileInfo f6 = new FileInfo(@"C:\Test5.txt"); using(StreamWriter swriter = f6.CreateText()) {
// Use the StreamWriter object... }
FileInfo f7 = new FileInfo(@"C:\FinalTest.txt"); using(StreamWriter swriterAppend = f7.AppendText()) {
// Use the StreamWriter object... }
}
Working with the
File
type
Working with the
File
type
static void Main(string[] args) {
// Obtain FileStream object via File.Create().
using(FileStream fs = File.Create(@"C:\test.dat")) { }
// Obtain FileStream object via File.Open().
using(FileStream fs2 = File.Open(@"C:\test2.dat",
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) { }
// Get a FileStream object with read-only permissions.
using(FileStream readOnlyStream = File.OpenRead(@“test3.dat")) { }
// Get a FileStream object with write-only permissions.
using(FileStream writeOnlyStream = File.OpenWrite(@“test4.dat")) { }
// Get a StreamReader object.
using(StreamReader sreader = File.OpenText(@"C:\boot.ini")) { }
// Get some StreamWriters.
using(StreamWriter swriter = File.CreateText(@"C:\test3.txt")) { }
using(StreamWriter swriterAppend = File.AppendText(@"C:\FinalTest.txt")) { } }
The File type provides functionality almost identical to that of the FileInfo type, using a number of static members. Like FileInfo, File supplies AppendText(), Create(),
CreateText(), Open(), OpenRead(), OpenWrite(), and OpenText() methods.
Additional
File
-centric members
Additional
File
-centric members
The File type also supports a few unique members, which can greatly simplify the processes of reading and writing textual data.
Method Meaning in life
ReadAllBytes() Opens the specified file, returns the binary data as an array of bytes, and then closes the file
ReadAllLines() Opens a specified file, returns the character data as an array of strings, and then closes the file
ReadAllText() Opens a specified file, returns the character data as a System.String, and then closes the file
WriteAllBytes() Opens the specified file, writes out the byte array, and then closes the file WriteAllLines() Opens a specified file, writes out an array of strings, and then closes the
file
WriteAllText() Opens a specified file, writes the character data, and then closes the file
Additional
File
-centric members
Additional
File
-centric members
using System; using System.IO; class Program {
static void Main(string[] args) {
Console.WriteLine("***** Simple IO with the File Type *****\n");
string[] myTasks = {"Fix bathroom sink", "Call Dave", "Call Mom and Dad", "Play Xbox 360"};
// Write out all data to file on C drive. File.WriteAllLines(@"C:\tasks.txt", myTasks); // Read it all back and print out.
foreach (string task in File.ReadAllLines(@"C:\tasks.txt")) {
Console.WriteLine("TODO: {0}", task); }
Console.ReadLine(); }
}
The
Directory(Info)
and
File(Info)
types
The
Directory(Info)
and
File(Info)
types
System.IO provides four types that allow you to manipulate individual files, as well as interact with a machine’s directory structure. The first two types, Directory and File, expose creation, deletion, copying, and moving operations using various static members.
The abstract FileSystemInfo base class
The abstract FileSystemInfo base class
The DirectoryInfo and FileInfo types receive many behaviors from the abstract
FileSystemInfo base class. For the most part, the members of the FileSystemInfo class are used to discover general characteristics (such as time of creation, various attributes, and so forth) about a given file or directory.
Property Meaning in Life
Attributes Gets or sets the attributes associated with the current file that are represented by the FileAttributes enumeration
CreationTime Gets or sets the time of creation for the current file or directory
Exists Can be used to determine whether a given file or directory exists
Extension Retrieves a file’s extension
FullName Gets the full path of the directory or file
LastAccessTime Gets or sets the time the current file or directory was last accessed
LastWriteTime Gets or sets the time when the current file or directory was last written to
Name Obtains the name of the current file or directory
Working with the DirectoryInfo Type
Working with the DirectoryInfo Type
You begin working with the DirectoryInfo type by specifying a particular directory path as a constructor parameter. If you want to obtain access to the current working directory (i.e., the directory of the executing application), use the "." notation.
Member Meaning in life
Create(),
CreateSubdirectory()
Create a directory (or set of subdirectories), given a path name
Delete() Deletes a directory and all its contents
GetDirectories() Returns an array of strings that represent all subdirectories in the current directory
GetFiles() Retrieves an array of FileInfo types that represent a set of files in the given directory
MoveTo() Moves a directory and its contents to a new path Parent Retrieves the parent directory of the specified path
Root Gets the root portion of a path
// Bind to the current working directory. DirectoryInfo dir1 = new DirectoryInfo(".");
// Bind to C:\Windows, using a verbatim string.
Working with the DirectoryInfo type
Working with the DirectoryInfo type
Once you have created a DirectoryInfo object, you can investigate the underlying directory contents using any of the properties inherited from FileSystemInfo.
class Program
{
static void Main(string[] args) {
Console.WriteLine("***** Fun with Directory(Info) *****\n"); ShowWindowsDirectoryInfo();
Console.ReadLine(); }
static void ShowWindowsDirectoryInfo() {
// Dump directory information.
DirectoryInfo dir = new DirectoryInfo(@"C:\Windows"); Console.WriteLine("***** Directory Info *****"); Console.WriteLine("FullName: {0}", dir.FullName); Console.WriteLine("Name: {0}", dir.Name);
Console.WriteLine("Parent: {0}", dir.Parent);
Console.WriteLine("Creation: {0}", dir.CreationTime); Console.WriteLine("Attributes: {0}", dir.Attributes); Console.WriteLine("Root: {0}", dir.Root);
Console.WriteLine("**************************\n"); }
Enumerating files with the DirectoryInfo type
Enumerating files with the DirectoryInfo type
In addition to obtaining basic details of an existing directory, you can extend the current example to use some methods of the DirectoryInfo type. First, let’s leverage the GetFiles()
method to obtain information about all *.jpg files located under the C:\Windows\Web\ Wallpaper directory.
static void DisplayImageFiles() {
DirectoryInfo dir = new DirectoryInfo(@"C:\Windows\Web\Wallpaper"); // Get all files with a *.jpg extension.
FileInfo[] imageFiles = dir.GetFiles("*.jpg"); // How many were found?
Console.WriteLine("Found {0} *.jpg files\n", imageFiles.Length); // Now print out info for each file.
foreach (FileInfo f in imageFiles) {
Console.WriteLine("***************************"); Console.WriteLine("File name: {0}", f.Name); Console.WriteLine("File size: {0}", f.Length); Console.WriteLine("Creation: {0}", f.CreationTime); Console.WriteLine("Attributes: {0}", f.Attributes); Console.WriteLine("***************************\n"); }
Creation and deletion of directories
Creation and deletion of directories
You can programmatically extend a directory structure using the
DirectoryInfo.CreateSubdirectory() method.
static void ModifyAppDirectory() {
DirectoryInfo dir = new DirectoryInfo("."); // Create \MyFolder off application directory. dir.CreateSubdirectory("MyFolder");
// Create \MyFolder2\Data off application directory. dir.CreateSubdirectory(@"MyFolder2\Data");
}
static void FunWithDirectoryType() {
// List all drives on current computer.
string[] drives = Directory.GetLogicalDrives(); Console.WriteLine("Here are your drives:");
foreach (string s in drives) Console.WriteLine("--> {0} ", s); // Delete what was created.
Console.WriteLine("Press Enter to delete directories"); Console.ReadLine();
try
{
Directory.Delete(string.Format(@"{0}\MyFolder", Environment.CurrentDirectory)); // The second parameter specifies whether you wish to destroy any subdirectories. Directory.Delete(string.Format(@"{0}\MyFolder2",
Environment.CurrentDirectory), true); }
catch (IOException e) {
Console.WriteLine(e.Message); }
Working with the DriveInfo class type
Working with the DriveInfo class type
The System.IO namespace provides a class named DriveInfo. Like Directory.GetLogicalDrives(), the static DriveInfo.GetDrives() method allows you to discover the names of a machine’s drives. Unlike Directory.GetLogicalDrives(), however, DriveInfo provides numerous other details (such as the drive type, available free space, volume label, and whatnot).
class Program
{
static void Main(string[] args) {
Console.WriteLine("***** Fun with DriveInfo *****\n"); // Get info regarding all drives.
DriveInfo[] myDrives = DriveInfo.GetDrives(); // Now print drive stats.
foreach (DriveInfo d in myDrives) {
Console.WriteLine("Name: {0}", d.Name); Console.WriteLine("Type: {0}", d.DriveType); // Check to see whether the drive is mounted. if (d.IsReady)
{
Console.WriteLine("Free space: {0}", d.TotalFreeSpace); Console.WriteLine("Format: {0}", d.DriveFormat);
Console.WriteLine("Label: {0}", d.VolumeLabel); Console.WriteLine();
} }
Console.ReadLine(); }
The abstract Stream class
The abstract Stream class
The abstract Stream class
The abstract Stream class
Member Meaning in life
CanRead, CanWrite Determine whether the current stream supports reading, seeking, and/or CanSeek writing. Close() Closes the current stream and releases any resources (such as sockets and file handles)
associated with the current stream. Internally, this method is aliased to the Dispose() method; therefore “closing a stream” is functionally equivalent to “disposing a stream.”
Flush() Updates the underlying data source or repository with the current state of the buffer and then clears the buffer. If a stream does not implement a buffer, this method does nothing. Length Returns the length of the stream, in bytes.
Position Determines the position in the current stream.
Read(), ReadByte() Read a sequence of bytes (or a single byte) from the current stream and advance the current position in the stream by the number of bytes read.
Seek() Sets the position in the current stream. SetLength() Sets the length of the current stream.
Write(), WriteByte() Write a sequence of bytes (or a single byte) to the current stream and advance the current position in this stream by the number of bytes written.
Working with FileStream
Working with FileStream
The FileStream class provides an implementation for the abstract Stream members in a manner appropriate for file-based streaming. It is a fairly primitive stream; it can read or write only a single byte or an array of bytes. In reality, you will not often need to directly interact with the members of the FileStream type. Rather, you will most likely make use of various stream wrappers, which make it easier to work with textual data or .NET types.
static void Main(string[] args) {
// Obtain a FileStream object.
using(FileStream fStream = File.Open(@"C:\myMessage.dat", FileMode.Create)) {
// Encode a string as an array of bytes. string msg = "Hello!";
byte[] msgAsByteArray = Encoding.Default.GetBytes(msg); // Write byte[] to file.
fStream.Write(msgAsByteArray, 0, msgAsByteArray.Length); // Reset internal position of stream.
fStream.Position = 0;
// Read the types from file and display to console. Console.Write("Your message as an array of bytes: "); byte[] bytesFromFile = new byte[msgAsByteArray.Length]; for (int i = 0; i < msgAsByteArray.Length; i++)
{
bytesFromFile[i] = (byte)fStream.ReadByte(); Console.Write(bytesFromFile[i]);
}
// Display decoded messages.
Console.Write("\nDecoded Message: ");
Console.WriteLine(Encoding.Default.GetString(bytesFromFile)); }
Working with StreamWriters and StreamReaders
Working with StreamWriters and StreamReaders
The StreamWriter and StreamReader classes are useful whenever you need to read or write character-based data (e.g., strings). Both of these types work by default with Unicode characters; however, you can change this by supplying a properly configured System.Text.Encoding object reference. To keep things simple, let’s assume that the default Unicode encoding fits the bill.
StreamReader derives from an abstract type named TextReader, as does the related
StringReader type. The TextReader base class provides a very limited set of functionality to each of these descendents, specifically the ability to read and peek into a character stream.
Member Meaning in Life
Close() This method closes the writer and frees any associated resources. In the process, the buffer is automatically flushed (again, this member is functionally equivalent to calling the Dispose() method).
Flush() This method clears all buffers for the current writer and causes any buffered data to be written to the underlying device, but does not close the writer.
Writing to a Text File
Writing to a Text File
To see the StreamWriter type in action, create a new Console Application named StreamWriterReaderApp. The following Main() method creates a new file named reminders.txt using the File.CreateText() method. Using the obtained StreamWriter object, you add some textual data to the new file, as shown here:
static void Main(string[] args) {
Console.WriteLine("***** Fun with StreamWriter / StreamReader *****\n"); // Get a StreamWriter and write string data.
using(StreamWriter writer = File.CreateText("reminders.txt")) {
writer.WriteLine("Don't forget Mother's Day this year..."); writer.WriteLine("Don't forget Father's Day this year..."); writer.WriteLine("Don't forget these numbers:");
for(int i = 0; i < 10; i++) writer.Write(i + " "); // Insert a new line.
writer.Write(writer.NewLine); }
Console.WriteLine("Created file and wrote some thoughts..."); Console.ReadLine();
Reading from a text file
Reading from a text file
Now you need to understand how to programmatically read data from a file using the corresponding StreamReader type.
Member Meaning in Life
Peek() Returns the next available character without actually changing the position of the reader. A value of -1 indicates you are at the end of the stream.
Read() Reads data from an input stream.
ReadBlock() Reads a maximum of count characters from the current stream and writes the data to a buffer, beginning at index.
ReadLine() Reads a line of characters from the current stream and returns the data as a string (a null string indicates EOF).
ReadToEnd() Reads all characters from the current position to the end of the stream and returns them as a single string.
static void Main(string[] args) {
// Now read data from file.
Console.WriteLine("Here are your thoughts:\n");
using(StreamReader sr = File.OpenText("reminders.txt")) {
string input = null;
while ((input = sr.ReadLine()) != null) {
Console.WriteLine(input); }
}
Working with StringWriters and StringReaders
Working with StringWriters and StringReaders
Using the StringWriter and StringReader types, you can treat textual information as a stream of in-memory characters. This can prove helpful when you wish to append character-based information to an underlying buffer.
static void Main(string[] args) {
// Create a StringWriter and emit character data to memory. using(StringWriter strWriter = new StringWriter())
{
strWriter.WriteLine("Don't forget Mother's Day this year...");
// Get a copy of the contents (stored in a string) and pump to console. Console.WriteLine("Contents of StringWriter:\n{0}", strWriter);
}
Console.ReadLine(); }
Because StringWriter and StreamWriter both derive from the same base class (TextWriter), the writing logic is more or less identical. However, given that nature of StringWriter, be aware that this class allows you to extract a System.Text.StringBuilder object via the GetStringBuilder() method:
using (StringWriter strWriter = new StringWriter()) {
strWriter.WriteLine("Don't forget Mother's Day this year..."); Console.WriteLine("Contents of StringWriter:\n{0}", strWriter); // Get the internal StringBuilder.
StringBuilder sb = strWriter.GetStringBuilder(); sb.Insert(0, "Hey!! ");
Console.WriteLine("-> {0}", sb.ToString()); sb.Remove(0, "Hey!! ".Length);
Working with BinaryWriter
Working with BinaryWriter
The final writer/reader sets you will examine here are BinaryReader and BinaryWriter, both of which derive directly from System.Object. These types allow you to read and write discrete data types to an underlying stream in a compact binary format. The BinaryWriter class defines a highly overloaded Write() method to place a data type in the underlying stream. In addition to Write(), BinaryWriter provides additional members that allow you to get or set the Stream-derived type and offers support for random access to the data.
Member Meaning in Life
BaseStream This read-only property provides access to the underlying stream used with the BinaryWriter object.
Close() This method closes the binary stream. Flush() This method flushes the binary stream.
Working with BinaryReader
Working with BinaryReader
The BinaryReader class complements the functionality offered by BinaryWriter.
Member Meaning in Life
BaseStream This read-only property provides access to the underlying stream used with the BinaryReader object.
Close() This method closes the binary reader.
PeekChar() This method returns the next available character without actually advancing the position in the stream.
Read() This method reads a given set of bytes or characters and stores them in the incoming array.
ReadXXXX() The BinaryReader class defines numerous read methods that grab the next type from the stream (ReadBoolean(), ReadByte(), ReadInt32(), and so forth).
static void Main(string[] args) {
// Open a binary writer for a file.
FileInfo f = new FileInfo("BinFile.dat");
using(BinaryWriter bw = new BinaryWriter(f.OpenWrite())) {
Console.WriteLine("Base stream is: {0}", bw.BaseStream); // Create some data to save in the file
double aDouble = 1234.67; int anInt = 34567;
string aString = "A, B, C"; // Write the data
bw.Write(aDouble); bw.Write(anInt); bw.Write(aString); }