Writing to a Text File
Writing to text files are useful when you want a way of permanent storage of your data. Although databases and XML files are more popular choices, text files are still used by many legacy software. And if you are writing a small amount of simple data, writing to a text file is an acceptable choice.
Before we write to a data, we need a stream, specifically a FileStream. A stream represents a file in your disk or you can even use streams that point to a remote destination. The FileStream class will be used to point to a file. The FileStream object is then passed as a parameter to the constructor of the StreamWriter class. The StreamWriter class is the one responsible for writing to the stream, that is, the file indicated by the stream. Note that both FileStream and StreamWriter classes are contained inside the System.IOnamespace.
The following program asks the user to enter first names, last names, and ages of people.
using System;
using System.IO;
using System.Text;
namespace WritingToFile
{
class Program
{
static void Main()
{
try
{
FileStream fs = new FileStream("sample.txt", FileMode.Create);
StreamWriter writer = new StreamWriter(fs);
StringBuilder output = new StringBuilder();
int repeat = 0;
do
{
Console.WriteLine("Please enter first name: ");
output.Append(Console.ReadLine() + "#");
Console.WriteLine("Please enter last name: ");
output.Append(Console.ReadLine() + "#");
Console.WriteLine("Please enter age: ");
output.Append(Console.ReadLine());
writer.WriteLine(output.ToString());
output.Clear();
Console.WriteLine("Repeat? 1-Yes, 0-No : ");
repeat = Convert.ToInt32(Console.ReadLine());
} while (repeat != 0);
writer.Close();
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Figure 1
Please enter first name: John Please enter last name: Smith Please enter age: 21 Repeat? 1-Yes, 0-No: 1 Please enter first name: Mike Please enter last name: Roberts Please enter age: 31 Repeat? 1-Yes, 0-No: 1 Please enter first name: Garry Please enter last name: Mathews Please enter age: 27 Repeat? 1-Yes, 0-No: 0
The output shows that we input three persons and they will be stored in a text file located in the path given when we created the FileStream object.
Line 13 creates a FileStream object. The path we provided is a relative path and has no parent directories so the text file will be found in the directory where the program executable is also located. The constructor of the FileStream class, as shown above, accepts the path of the file and a FileMode enumeration value. The FileMode enumeration specifies how the operating system will open the file. The values available are shown below:
Value | Description |
---|---|
Append | Seeks the end of the file and starts the writing there. If the file does not exist, it is created. |
Create | Creates a file. If the file already exists, it will be overwritten. |
CreateNew | Creates a new file. If the file already exists, a System.IO.IOException is thrown. |
Open | Opens an existing file. A value from System.IO.FileAccess enumeration determines the behavior of this value. System.IO.FileNotFoundException is thrown if the file is not found. |
OpenOrCreate | Same as Open but creates a new file if the file does not exist. |
Truncate | Specifies that the operating system should open an existing file. Once opened, the file should be truncated so that its size is zero bytes. |
Figure 2
Passing FileMode.Create simply means create the file and if the file already exists, it will be overwritten. If we want to append new persons to the file, then we can use FileMode.Append instead. Another enumeration, System.IO.FileAccess, determines the capabilities you can do with the file. The values are listed below.
Value | Description |
---|---|
Read | Only grants read access to a file. |
Write | Only grants write access to a file. |
ReadWrite | Grants read/write access to a file. |
Figure 3
To use this enumeration, you need to use a different constructor of the FileStream class which accepts a third argument which is a value from the FileAccess enumeration.
FileStream fs = new FileStream("sample.txt", FileMode.Create, FileAccess.ReadWrite);
After we successfully created the FileStream object, we need to pass it to the StreamWriter class’ constructor.
StreamWriter writer = new StreamWriter(fs);
The StreamWriter class contains the actual methods for writing data to the file. Such methods are shown below.
Value | Description |
---|---|
Write | Writes the data to the file. |
WriteLine | Writes the data to the file and adds a newline character at the end. |
Close | Closes the StreamWriter and the underlying stream. |
Figure 4
We used an instance of StringBuilder to build the output (lines 20-25). Note that we added a “#” character between at the end of firstname and lastname. It is used as a delimiter so that it will be easy for us to separate each component when we will be reading the data in the next lesson. You can use any special character as a delimiter, but # or $ is the most widely used.
Lastly, we need to close the StreamWriter using the Close() method(line 32).This releases the resources in the memory and also closes the stream associated to it.
We enclosed everything in a try block because these operations can throw a System.IO.IOException. For example, if the file cannot be found, then this exception will be thrown. Lines 34-37 catches this exception.
Let’s now look at the created file.
John#Smith#21
Mike#Roberts#31
Garry#Matthews#27
Each line represents a person, and each person is composed of three fields separated by a delimiter. The next lesson will retrieve each person from this file.