by kirupa |
29 March 2007Simply 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.
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.
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.
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.
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.
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! 😇

|