The .NET Framework makes it
easy to create simple "flat" files in text or binary format. Unlike a
database, these files don't have any internal structure (that's why
they're called flat). Instead, these files are really just a list of
whatever information you want to store.
1. Text Files
You can write to a file and read from a file using a
StreamWriter and a StreamReader—dedicated classes that abstract away the
process of file interaction. There really isn't much to it. You can
create the StreamWriter and StreamReader classes on your own, or you can
use one of the helpful shared methods included in the File class, such
as CreateText() or OpenText().
Here's an example that gets a StreamWriter for writing data to the file c:\myfile.txt:
' Define a StreamWriter (which is designed for writing text files).
Dim w As StreamWriter
' Create the file, and get a StreamWriter for it.
w = File.CreateText("c:\myfile.txt")
When you call the CreateText() method, you create the
file and receive the StreamWriter object. At this point, the file is
open and ready to receive your content. You need to write your data to
the file and then close it as soon as possible.
Using the StreamWriter, you can call the WriteLine()
method to add information to the file. The WriteLine() method is
overloaded so it can write many simple data types, including strings,
integers, and other numbers. These values are essentially all converted
into strings when they're written to a file and must be converted back
into the appropriate types manually when you read the file.
w.WriteLine("This file generated by ASP.NET") ' Write a string.
w.WriteLine(42) ' Write a number.
When you finish with the file, you must make sure to
close it by calling the Close() or Dispose() method. Otherwise, the
changes may not be properly written to disk, and the file could be
locked open.
w.Close()
Finally, when you're debugging an application that
writes to files it's always a good idea to look at what you wrote using a
text editor like Notepad. Figure 1 shows the contents that are created in c:\myfile.txt with the simple code you've considered.
To read the information, you use the corresponding
StreamReader class. It provides a ReadLine() method that gets the next
available value and returns it as a string. ReadLine() starts at the
first line and advances the position to the end of the file, one line at
a time.
Dim r As StreamReader = File.OpenText("c:\myfile.txt")
Dim inputString As String
inputString = r.ReadLine() ' = "This file generated by ASP.NET"
inputString = r.ReadLine() ' = "42"
ReadLine() returns a null reference when there is no
more data in the file. This means you can read all the data in a file
using code like this:
' Read and display the lines from the file until the end
' of the file is reached.
Dim line As String
Do
line = r.ReadLine()
If line IsNot Nothing Then
' (Process the line here.)
End If
Loop Until line Is Nothing
As when writing to a file, you must close the file once you're finished:
r.Close()
The code you've seen so far opens a file in
single-user mode. If a second user tries to access the same file at the
same time, an exception will occur. You can reduce this problem when
opening files using the more generic four-parameter version of the
File.Open() method instead of File.OpenText(). You must specify
FileShare.Read for the final parameter. Unlike the OpenText() method,
the Open() method returns a FileStream object, and you must manually
create a StreamReader that wraps it.
Here's the code you need to create a multiuser-friendly StreamReader:
Dim fs As FileStream
fs = File.Open("c:\myfile.txt", FileMode.Open, _
FileAccess.Read, FileShare.Read)
Dim r As New StreamReader(fs)
2. Binary Files
You can also read and write to binary files. Binary
data uses space more efficiently but also creates files that aren't
human-readable. If you open a file in Notepad, you'll see a lot of
extended ASCII characters (politely known as gibberish).
To open a file for binary writing, you need to create
a new BinaryWriter object. The constructor accepts a stream, which you
can retrieve using the File.OpenWrite() method. Here's the code to open
the file c:\binaryfile.bin for binary writing:
Dim fs As FileStream = File.OpenWrite("c:\binaryfile.bin")
Dim w As New BinaryWriter(fs)
.NET concentrates on stream objects, rather than the
source or destination for the data. This means you can write binary data
to any type of stream, whether it represents a file or some other type
of storage location, using the same code. In addition, writing to a
binary file is almost the same as writing to a text file.
Dim str As String = "ASP.NET Binary File Test"
Dim int As Integer = 42
w.Write(str)
w.Write(int)
w.Close()
Reading data from a binary file is easy, but not
quite as easy as reading data from a text file. The problem is that you
need to know the data type of the data you want to retrieve. To retrieve
a string, you use the ReadString() method. To retrieve an integer, you
must use ReadInt32(). That's why the preceding code example writes
variables instead of literal values. If the value 42 were hard-coded as
the parameter for the Write() method, it wouldn't be clear if the value
would be written as a 16-bit integer, 32-bit integer, decimal, or
something else. Unfortunately, you may need to micromanage binary files
in this way to prevent errors.
Dim r As New BinaryReader(File.OpenRead("c:\binaryfile.bin"))
Dim str As string
Dim int As Integer
str = r.ReadString()
int = r.ReadInt32()
r.Close()
Once again, if you want to use file sharing, you need
to use File.Open() instead of File.OpenRead(). You can then create a
BinaryReader by hand, as shown here:
Dim fs As FileStream
fs = File.Open("c:\binaryfile.bin", FileMode.Open, _
FileAccess.Read, FileShare.Read)
Dim r As New BinaryReader(fs)
NOTE
You have no easy way to
jump to a location in a text or binary file without reading through all
the information in order. Although you can use methods such as Seek() on
the underlying stream, you need to specify an offset in bytes, which
involves some fairly involved calculations based on data type sizes. If
you need to store a large amount of information and move through it
quickly, you need a dedicated database, not a binary file.