Why write in files ?
You might be thinking that why would someone would write a file when we have
all the databases available in which we can store our data. There are many applications
in which we need to backup the database or to send the data to another user through
email. In all those applications you can use any database but the same operations
can also be performed using a file system.
Another good reason for saving in file is some companies cannot afford to buy
expensive databases and their only choice to collect data is in the form of files,
typically xml files.
Different types of files ?
There are infinite types of files. If I want to define all of them I simply can't
since they are infinite :). I will only use the most common type file system. This
file system includes text files, binary files and xml files. In this article we
will see how we can write and read these different type of files.
Security related issues in Reading/Writing Files
Before reading and writing files you must check that that accunt you are using
has permission to read/write a file. If you don't have any writing permission you
can easily give to the required account. By default Asp.net uses ASP.net user account
to run .net applications, most probably your ASP.net account may not have persmissions
to write files. You can easily grant the permission to the ASP.net account.
Simply, right click on the file and select properties. Then select the Security
tab and add ASP.net user to use this file. You can give various permissions to the
account using various options displayed under the security tab. Once you have setup
the permissions you are ready to write the file.
Writing Text Files :
Text files are the most common type of files. You can make text files in every
editor, notepad is preferably used to create text files. The extension of the text
file is .txt . Lets see what Microsoft.net class libraries provide us for writing
and reading text files. Lets first make a simple interface that lets us enter some
data in the multiline textbox. Your interface will look like the image below:

Button Click Code:
After making the interface let see some of the code. All the code in this example
will be written in the Button click event handler since we want the file to be written
when the button is clicked.
// Don't forget to import System.IO namespace
private void Button1_Click(object sender, System.EventArgs e)
{
FileStream fs = File.Create(Server.MapPath("test.txt"));
StreamWriter sw = new StreamWriter(fs);
sw.Write(TextBox1.Text);
sw.Close();
fs.Close();
}
As you can see the code is really simple. Lets examine the code and see whats
going on.
1. First of all don't forget to import the System.IO namespace.
2. Make the object of FileStream class. The FileStream class is your best option
when you don't care about the internal structure of the files with which you're
working.
3. Next we make the object of the StreamWriter class. You can think of StreamWriter
class as an additional layer of functionality on top of the FileStream class.
4. File.Create method makes a new file. The Server.MapPath means that file will
be created in the virtual folder of IIS which will be located at C:\inetpub\wwwroot\YourProjectFolder\
5. Next we write the Text from the TextBox to the file using the StreamWriter
Write method.
6. Finally and the most important step is to close the FileStream object explicitly
using the Close method.
There are many other ways of writing text to files. One of the way is to use
the TextWriter class. For more information about the TextWriter class visit this
link
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemiotextwriterclasstopic.asp
Reading Text Files :
We have seen how we can write the Text Files lets see how we can read from the
text files. Reading is also as simple as writing the text files. Lets look at the
reading code below:
private void Button1_Click(object sender, System.EventArgs e)
{
FileStream fs = File.OpenRead(Server.MapPath("test.txt"));
StreamReader sr = new StreamReader(fs);
while(sr.Peek() > -1)
{
Response.Write(sr.ReadLine());
}
sr.Close();
fs.Close();
}
Lets see what the code does:
1. First we made the FileStream object and tells it to open the file "test.txt".
2. We make the StreamReader object and tell it what FileStream to read.
3. The while loop checks the end of the file when the end of the file is reached
sr.Peak() returns '-1' and the loop breaks.
4. Finally we close the StreamReader and FileStream objects.
Writing Binary Files :
For files with known internal structures, the BinaryReader and BinaryWriter classes
offer streaming functionality that's oriented towards particular data types. The
good thing about writing binary files are you cannot read the files by just opening
them in the notepad also binary files can be of very large size. Lets look at the
code to create Binary files.
private void Button1_Click(object sender, System.EventArgs e)
{
FileStream fs = File.Create(Server.MapPath("test.dat"));
BinaryWriter bw = new BinaryWriter(fs);
int x = 10;
decimal d = 3.234M;
string str = "Hello World";
bw.Write(x);
bw.Write(d);
bw.Write(str);
bw.Close();
fs.Close();
}
Okay now lets see whats happening in the code:
1. First we made the FileStream object but in this case we are writing the .dat
file which means the data file.
2. We created an object of the binarywriter class.
3. Later we declared three variables of type int, decimal and string.
4. Finally we wrote the three variables in the binary file.
If you go and see the file and try to open the file in notepad you will only
see some strange characters. In other words you won't be able to see the text.
Reading Binary Files :
Lets see how we can read the Binary files.
private void Button1_Click(object sender, System.EventArgs e)
{
FileStream fs = File.OpenRead(Server.MapPath("test.dat"));
BinaryReader br = new BinaryReader(fs);
Response.Write(br.ReadInt32());
Response.Write(br.ReadDecimal());
Response.Write(br.ReadString());
br.Close();
fs.Close();
}
As you can see the Reading code for Binary Files is also very simple. If you
have noticed the code is a bit different from which we saw earlier for reading Text
files. Here we are extracting the datatypes that we wrote in the binary file. We
use ReadInt32() method to read the integar out from the binary file. We use ReadDecimal()
to read the decimal values from the binary file and so on.
Writing XML Files :
Okay lets see how we can write XML files. Writing and Reading Xml files are most
important because they are also serve a purpose of a database. Lets see how we can
write and read xml files.
Typically, you use an XmlTextWriter if you need to write XML as raw data without
the overhead of a DOM. The XmlTextWriter is an implementation of the XmlWriter class
that provides the API which writes XML to file, stream, or a TextWriter. This class
provides numerous validation and checking rules to ensure that the XML being written
is well formed. When certain violations occur, exceptions are thrown and these exceptions
should be caught. The XmlTextWriter has different constructors, each of which specifies
a different type of the location to which to write the XML data. This sample uses
the constructor that writes XML to a file. In particular, the following sample code
constructs an XmlTextWriter with a string representing the file location for the
newbooks.xml file.
XmlTextWriter myXmlTextWriter = new XmlTextWriter ("newbooks.xml", null);
C# Code:
myXmlTextWriter.Formatting = Formatting.Indented;
myXmlTextWriter.WriteStartDocument(false);
myXmlTextWriter.WriteDocType("bookstore", null, "books.dtd", null);
myXmlTextWriter.WriteComment("This file represents another fragment of a book store inventory database");
myXmlTextWriter.WriteStartElement("bookstore");
myXmlTextWriter.WriteStartElement("book", null);
myXmlTextWriter.WriteAttributeString("genre","autobiography");
myXmlTextWriter.WriteAttributeString("publicationdate","1979");
myXmlTextWriter.WriteAttributeString("ISBN","0-7356-0562-9");
myXmlTextWriter.WriteElementString("title", null, "The Autobiography of Mark Twain");
myXmlTextWriter.WriteStartElement("Author", null);
myXmlTextWriter.WriteElementString("first-name", "Mark");
myXmlTextWriter.WriteElementString("last-name", "Twain");
myXmlTextWriter.WriteEndElement();
myXmlTextWriter.WriteElementString("price", "7.99");
myXmlTextWriter.WriteEndElement();
myXmlTextWriter.WriteEndElement();
//Write the XML to file and close the myXmlTextWriter
myXmlTextWriter.Flush();
myXmlTextWriter.Close();
In creating this element, the preceding sample code also shows how, for each
XML node type, there is corresponding XML write method. For example, writing an
element calls the WriteElementString method and writing an attribute calls the WriteAttributeString
method. For nested levels, you use the WriteStartElement/WriteEndElement pair and,
for more complex attribute creation, you can use the WriteStartAttribute/WriteEndAttribute
pair.
When writing XML, notice how the sample code writes the XML declaration with
the version "1.0" using the WriteStartDocument method. If you want the writer to
check that the document is well formed (XML declaration first, DOCTYPE in prolog,
only one root level element, and so on), you must call this optional WriteStartDocument
method before calling any other write method. Next, the code calls the WriteDocType
method to writes the document type with the name "bookstore". The third parameter
in the call to the WriteDocType specifies that the writer is to write SYSTEM "books.dtd".
By writing this, the XML file indicates that there is an external DTD to validate
against.
Finally, the sample code calls the Flush method to persist the XML data to a
file before calling the Close method. (While this sample only really requires the
Close method, there are occasions where the XML generated needs to be persisted
and the writer reused.)
To check the output from the XmlTextWriter, perform a round trip test by reading
in the generated file with an XmlTextReader to validate that the XML is well formed.
Reading Xml Files :
XmlReader class is the API that provides XML parsing, the XmlTextReader is the
implementation designed to handle byte streams.
Typically, you use the XmlTextReader if you need to access the XML as raw data
without the overhead of a DOM. Not having to access the DOM results in a faster
way to reading XML. For example, an XML document could have a header section used
for routing the document for processing elsewhere. The XmlTextReader has different
constructors to specify the location of the XML data. This sample loads XML from
the
books.xml file, as shown in the following code.
XmlTextReader reader = new XmlTextReader ("books.xml");
Once loaded, the XmlTextReader moves across the XML data by using the Read method
sequentially retrieving the next record from the document. The Read method returns
false if there are no more records.
while (reader.Read())
{
// Do some work here on the data
...
}
To process the XML data, each record has a node type that can be determined
from the NodeType property. After the NodeType enumeration returns the node
type, the sample tests the node type to see whether it is either an element
or document type. If the node is either one of these two types, the sample processes
the node using the Name and Value properties to display details about the node.
The Name property returns the node name (for instance, the element and attribute
names, while the Value property returns the node value (node text) of the current
node (record).
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an Element
Console.Write("<" + reader.Name);
while (reader.MoveToNextAttribute()) // Read attributes
Console.Write(" " + reader.Name + "='" + reader.Value + "'");
Console.Write(">");
break;
case XmlNodeType.DocumentType: // The node is a DocumentType
Console.WriteLine(NodeType + "<" + reader.Name + ">" + reader.Value);
break;
...
}
}
The XmlNodeType returned depends on the XmlReader class being used. For example,
the XmlTextReader class never returns an XmlNodeType that is a Document, DocumentFragment,
Entity, EndEntity and Notation node. See the .NET Framework Class Library for details
on what XmlNodeType are returned by each XmlReader class.
I hope you liked the article, happy coding !