Character-Based File IO


Character-Based File I/O

Although byte-oriented file handling is quite common, C# also supplies character-based streams. The advantage to the character streams is that they operate directly on Unicode characters. Thus, if you want to store Unicode text, the character streams are certainly your best option. In general, to perform character-based file operations, you will wrap a FileStream inside either a StreamReader or a StreamWriter. These classes automatically convert a byte stream into a character stream, and vice versa.

Remember, at the operating system level, a file consists of a set of bytes. Using a StreamReader or StreamWriter does not alter this fact.

StreamWriter is derived from TextWriter. StreamReader is derived from TextReader. Thus, StreamWriter and StreamReader have access to the methods and properties defined by their base classes.

Using StreamWriter

To create a character-based output stream, wrap a Stream object (such as a FileStream) inside a StreamWriter. StreamWriter defines several constructors. One of its most popular is shown here:

 StreamWriter(Stream stream)

Here, stream is the name of an open stream. This constructor throws an ArgumentException if stream is not opened for output and an ArgumentNullException if stream is null. Once created, a StreamWriter automatically handles the conversion of characters to bytes.

Here is a simple key-to-disk utility that reads lines of text entered at the keyboard and writes them to a file called “test.txt”. Text is read until the user enters the word “stop”. It uses a FileStream wrapped in a StreamWriter to output to the file.

 /* A simple key-to-disk utility that    demonstrates a StreamWriter. */ using System; using System.IO; class KtoD {   public static void Main() {     string str;     FileStream fout;     try {       fout = new FileStream("test.txt", FileMode.Create);     }     catch(IOException exc) {       Console.WriteLine(exc.Message + "Cannot open file.");       return ;     }     StreamWriter fstr_out = new StreamWriter(fout);     Console.WriteLine("Enter text ('stop' to quit).");     do {       Console.Write(": ");       str = Console.ReadLine();       if(str != "stop") {         str = str + "\r\n"; // add newline         try {           fstr_out.Write(str);         } catch(IOException exc) {           Console.WriteLine(exc.Message + "File Error");           return ;         }       }     } while(str != "stop");     fstr_out.Close();   } }

In some cases, it might be more convenient to open a file directly using StreamWriter. To do so, use one of these constructors:

 StreamWriter(string filename) StreamWriter(string filename, bool appendFlag)

Here, filename specifies the name of the file to open, which can include a full path specifier. In the second form, if appendFlag is true, then output is appended to the end of an existing file. Otherwise, output overwrites the specified file. In both cases, if the file does not exist, it is created. Also, both throw an IOException if an I/O error occurs. Other exceptions are also possible.

Here is the key-to-disk program rewritten so that it uses StreamWriter to open the output file:

 // Open a file using StreamWriter. using System; using System.IO; class KtoD {   public static void Main() {     string str;     StreamWriter fstr_out;     // Open the file directly using StreamWriter.     try {       fstr_out = new StreamWriter("test.txt");     }     catch(IOException exc) {       Console.WriteLine(exc.Message + "Cannot open file.");       return ;     }     Console.WriteLine("Enter text ('stop' to quit).");     do {       Console.Write(": ");       str = Console.ReadLine();       if(str != "stop") {         str = str + "\r\n"; // add newline         try {           fstr_out.Write(str);         } catch(IOException exc) {           Console.WriteLine(exc.Message + "File Error");           return ;         }       }     } while(str != "stop");     fstr_out.Close();   } }

Using a StreamReader

To create a character-based input stream, wrap a byte stream inside a StreamReader.StreamReader defines several constructors. A frequently used one is shown here:

 StreamReader(Stream stream)

Here, stream is the name of an open stream. This constructor throws an ArgumentNullException if stream is null. It throws ArgumentException if stream is not opened for input. Once created, a StreamReader will automatically handle the conversion of bytes to characters.

The following program creates a simple disk-to-screen utility that reads a text file called “test.txt” and displays its contents on the screen. Thus, it is the complement of the key-to-disk utility shown in the previous section.

 /* A simple disk-to-screen utility that    demonstrates a StreamReader. */ using System; using System.IO; class DtoS {   public static void Main() {     FileStream fin;     string s;     try {       fin = new FileStream("test.txt", FileMode.Open);     }     catch(FileNotFoundException exc) {       Console.WriteLine(exc.Message + "Cannot open file.");       return ;     }     StreamReader fstr_in = new StreamReader(fin);     // Read the file line-by-line.     while((s = fstr_in.ReadLine()) != null) {       Console.WriteLine(s);     }     fstr_in.Close();   } }

Notice how the end of the file is determined. When the reference returned by ReadLine( ) is null, the end of the file has been reached.

As with StreamWriter, in some cases you might find it easier to open a file directly using StreamReader. To do so, use this constructor:

 StreamReader(string filename)

Here, filename specifies the name of the file to open, which can include a full path specifier. The file must exist. If it doesn’t, a FileNotFoundException is thrown. If filename is null, then an ArgumentNullException is thrown. If filename is an empty string, ArgumentException is thrown. IOException (filename/path is incorrect) and DirectoryNotFoundException (path specifies an invalid directory) are also possible.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net