Reading and Writing Text-Based Files - Page 1
       by kirupa  |  29 March 2007

Simply put, a file is nothing more than a container holding a collection of data. The data a file contains can be anything ranging from bits representing text to images to sounds, etc. In this tutorial, you will learn how to read text from files and write text back to files using the StreamReader and StreamWriter Classes.

How Files Are Read/Written
In most operating systems, a file is associated with a particular application designated to read it. When reading a file, an application takes the collection of data and loads it into memory for further processing. When an application is said to read a file, the file's contents may load the data sequentially in fixed chunks, or the entire file may be loaded into memory and read in bulk. These details aren't too important for us, because the .NET classes we use take care of a lot of these details for us.

Reading Files
To read a file, you need to know only the valid path of a file. Once you have the path to a file, you load the file into memory until there is nothing more to load. To facilitate this, you have the System.IO namespace's StreamReader class that provides a lot of the functionality needed to read a file for you.

First, find a text file. If you cannot find a text file, copy and paste the following Dave Barry quote into Notepad and save it into an easily accessible location:

For this example, I saved the above quote on my Desktop and called it quote.txt. With your text file set, the following code sample shows you how to read a file from your drive:

StreamReader reader = new StreamReader("C:\\Users\\Kirupa\\Desktop\\quote.txt");
 
string readerLine = reader.ReadLine();
 
while (readerLine != null)
{
Console.WriteLine(readerLine);
readerLine = reader.ReadLine();
}

When I run through the above code, I see each line from my quote.txt file displayed in the console:

Let's go through our above code line by line:


StreamReader reader = new StreamReader("C:\\Users\\Kirupa\\Desktop\\quote.txt");

First, let's create a reader object that is of type StreamReader. As part of the StreamReader constructor, I am passing in the path to my text file. Notice that the folders in the path are not separated by single slashes as  C:\Users\Kirupa\Desktop\quote.txt. Instead, the folder paths are delimited by double slashes because of the way strings in .NET are parsed.


string readerLine = reader.ReadLine();

Next, I create a new string variable called readerLine. I initialize readerLine to the first line from our text file by using the reader object's ReadLine() method.


while (readerLine != null)
{
Console.WriteLine(readerLine);
readerLine = reader.ReadLine();
}

The above loop is where the main reading of your file takes place. The loop will run as long as our readerLine variable still holds some text from our text file. As you progress through the loop, you set the readerLine variable equal to the next line from our text file by using the ReadLine() method.

Once you reach the end of your text file, reader.ReadLine() will return a null because there are no more lines of text to show. Once the null value is returned, our readerLine variable also equals null, and if you recall, our loop only loops when readerLine is not equal to null!


Reading a file is fairly straightforward. The only thing to watch out for is making sure you are ending your loop properly. Common mistakes I've made include forgetting to initialize the readerLine variable to the first line of text prior to looping. That causes your loop to break immediately. Another mistake I made is forgetting to set the readerLine variable equal to the next line inside the loop.

Besides what I listed above, reading files should is pretty straightforward. Of course, reading files is only half the fun! In the next section, you will learn how to write your own file.

Writing Files
In this section, you will learn how to take string data and write it to a file. While writing a file seems more complicated, it actually takes fewer steps than when you are reading a file.

To write a file, all you really need to do is specify the location of your saved file and have some text that you need to write:

StreamWriter writer = new StreamWriter("C:\\Users\\Kirupa\\Desktop\\foo.txt");
writer.WriteLine("Hello world!");
writer.Close();

Let's dive right into what the code actually does:


StreamWriter writer = new StreamWriter("C:\\Users\\Kirupa\\Desktop\\foo.txt");

In this line, I create a new StreamWriter object called writer. The StreamWriter constructor takes a file as an argument. The file you specify is where your data will be written to. If the file you specify does not exist, that file will be created automatically for you. If the file already exists, and no other program is currently accessing it, you will overwrite it.


writer.WriteLine("Hello world!");

In this line, you specify the text to write to your file. The WriteLine method can take a string as its argument, and in the above line, I am passing in the text "Hello World!"


writer.Close();

In this line, we commit the change we made by closing the connection. If you do not close the StreamWriter object, any text you write or modifications you make will not be saved.


As you can see, writing a line of text to a file is not too complicated. The main thing to remember is that there is no functionality to append data to the end of a file. Any data you add overwrites the existing file with the new data, so unless you want to lose your data, make sure to read and store the existing data first.

Checking if a File Exists
You cannot read a file that does not exist, and you may not want to overwrite an existing file. Both of these scenarios can be avoided by checking if the file you are writing to exists first. You can check if a File exists by using File.Exists():

string filePath = "C:\\Users\\Kirupa\\Desktop\\foo.txt");
 
if (File.Exists(filePath))
{
// File exists
}
else
{
// File does not exist
}

Something to remember is that a file is created or overwritten when your StreamWriter is initialized with the path to your file. Therefore, something like the following will not work like you would want to:

string filePath = "C:\\Users\\Kirupa\\Desktop\\foo.txt";
 
StreamWriter foo = new StreamWriter(filePath);
 
if (File.Exists(filePath))
{
// File exists
}
else
{
// File does not exist
}

The reason is that the moment your StreamWriter object foo is initialized, the file pointing to by filePath will be created or overwritten. Our File.Exists boolean will always return true because no matter what you reasonably do, a file at filePath will exist.

If you want to avoid overwriting an existing file, the following approach works better:

string filePath = "C:\\Users\\Kirupa\\Desktop\\foo.txt";
 
StreamWriter foo;
 
if (File.Exists(filePath))
{
// File exists
// Don't do anything.
}
else
{
// File does not exist
foo = new StreamWriter(filePath);
foo.Write("Blarg. Zorb. Zeeb. Foo.");
foo.Close();
}

In the above code, a file is created only if File.Exists returns false. Notice that our StreamWriter object foo isn't being initialized until our code reaches the File.Exists == false condition.


Asynchronous File Handling
Both the StreamReader and StreamWriter classes work asynchronously. That's a cool sounding word that basically means that you can do other things when using StreamReader or StreamWriter. To take a real world example, if you were opening a huge text file, you can continue to use your application and everything will seem to work fine without suffering delays or lags associated with reading your file.

If both of those classes were not asynchronous, then you would have to use Threads to ensure any time consuming reading or writing task operates semi-independently from other tasks. Threads is an interesting topic that I will save for a later article.

Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy my books, became a paid subscriber, watch my videos, and/or interact with me on the forums.

Your support keeps this site going! 😇

Kirupa's signature!

 

 

1 | 2 | 3




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.