Overview of File Processing

Introduction

So far in the Web project we had created, if we requested information from a visitor of a webpage, when the webpage closed on the browser, we lost all information that the user had entered. This is because such information was only temporarily stored in the random-access memory (RAM) of the visitor's computer. In some cases, you will want to "keep" information (data) for any reason you judge necessary.

File processing consists of storing information in a medium such as the computer memory, a hard drive, a CD/DVD, a USB drive, etc, so that you can "call" or get that information anytime.

File Processing

Introduction to Files

A file is a series of bytes of data that are arranged in a manner to produce a usable document. When these bytes belong to a single but common entity and hold values that are stored on a medium, the group is referred to as a file.

To indicate a file you want to use, you can declare a variable of type string and assign the name of the file to it. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string fileName = "Employees";
}
</body>
</html>

You can also declare the variable using the var or the dynamic keyword. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    var strCustomer = "Account927-004";
    string strEmployee = "EmplNbr248";
    dynamic strStoreItem = "BlackDress";
}
</body>
</html>

The above declarations indicate that the file is, or will be, in the IIS Express sub-folder of the Program Files (x86) folder on the C: drive. This is never a good idea. One alternative is to first create a folder (and sub-folders if necessary) and use that location for the file.

When indicating the location and name of the file, you can double each backslash to encode the string. Here are examples:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    var     strCustomer  = "C:\\Account927-004";
    dynamic strEmployees = "C:\\Human Resources\\EmplNbr248";
    string  strStoreItem = "C:\\General Inventory\\Store Items\\BlackDress";
}
</body>
</html>

As an alternative, instead of doubling the backslashes, you can start the string with @. When you use this symbol, you can still double the backslashes but you can use single backslashes. Here are example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    var     strCustomer  = @"C:\Account927-004";
    dynamic strEmployees = @"C:\Human Resources\EmplNbr248";
    string  strStoreItem = @"C:\General Inventory\Store Items\BlackDress";
}
</body>
</html>

Introduction to Streams

File processing consists of creating, storing, and/or retrieving the contents of a file from a recognizable medium. A stream is the techniques and means of performing file processing. To manage files stored in a computer, each file must provide basic pieces of information about itself. This basic information is specified when the file is created but can change during the lifetime of a file.

To support file processing, the .NET Framework provides a namespace named System.IO that contains various classes to handle any type of file operation. Therefore, to perform file processing, you can include the System.IO namespace in your project. Normally, if you are writing your code in the HTML document of a webpage, the file processing classes are automatically available.

The parent class of file processing is named Stream. With Stream, you can write (or store) data to a stream or you can read (or retrieve) data from a stream. Stream is an abstract class. As an abstract class, Stream is used as the parent of the classes that implement the necessary operations.

You will usually use a combination of classes to perform a typical operation. For example, some classes are used to create a stream object while some others are used to write data to the created stream.

Introduction to File Streaming

The fundamental operation performed on a file consists of writing data, such as text, to it. To assist you with this, the .NET Framework provides a class named FileStream. The FileStream class is derived from the Stream abstract class.

public class FileStream : System.IO.Stream

Besides the ability to write and read data based on operations inherited from the Stream class, the FileStream class adds some new operation we will review.

Fundamental Operations on Files

Introduction

To perform an operation on a file, you can declare a variable of type FileStream. This class is equipped with many constructors for various goals.

The Mode of a File

When accessing a file, one option you will most likely specify to the operating system is referred to as the mode of a file. It is specified through an enumeration named FileMode. To support it, the FileStream class provides the following constructor:

public FileStream(string path, FileMode mode);

The first argument represents the file. The second argument specifies the mode applied to the file. The members of the FileMode enumeration are:

Here is an example of starting a file:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
}
</body>
</html>

Binary Stream Writing

A streaming operation is primarily used to create a stream. Once the stream is ready, you can write data to it. The writing operation is performed through various classes. One of these classes is named BinaryWriter.

The BinaryWriter class can be used to write values of primitive data types (char, int, float, double, etc). To use a BinaryWriter value, you can first declare its variable, using one of the class' three constructors. One of its constructors uses the following syntax:

public BinaryWriter(Stream output);

This constructor takes as argument a Stream value, which could be a FileStream variable. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{ 
    string strStoreItems = @"C:\Department Store\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);
}
</body>
</html>

If you are initializing a variable while you are creating it, remember that you can use the var or the dynamic keyword to declare a variable.

To allow you to write data to a file, the BinaryWriter class is equipped with a method named Write. This method takes as argument the value that must be written to the stream. The method is overloaded so that there is a version for each primitive data type. Here is an example that adds strings to a newly created file:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

    bwStoreItems.Write("Floral Blouson Midi Dress");
    bwStoreItems.Write("Heathered Sweatpants");
    bwStoreItems.Write("Bellow Leather Knee-High Boots");
    bwStoreItems.Write("Pleated A-Line Skirt");
    bwStoreItems.Write("Long Sleeve Blouse");
}
</body>
</html>

Closing a Stream

When you use a stream, it requests resources from the computer and uses them while the stream is available. When you are not using the stream anymore, you should free the resources it was using and make them available again to the operating system so that other services can use them. This is done by closing the stream.

To let you close a stream, the Stream is equipped with a method named Close that its child classes inherit. The syntax of this method is:

public virtual void Close();

This method is called to simply close a stream. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

    bwStoreItems.Write("Floral Blouson Midi Dress");
    bwStoreItems.Write("Heathered Sweatpants");
    bwStoreItems.Write("Bellow Leather Knee-High Boots");
    bwStoreItems.Write("Pleated A-Line Skirt");
    bwStoreItems.Write("Long Sleeve Blouse");

    fsStoreItems.Close();
}
</body>
</html>

This method is called to simply close a stream. In the same way, the BinaryWriter class is equipped with a Close() method. When many objects are calling a Close() method, it is a good idea to call it starting with the last variable that was used. Here are examples of calling it on a stream and a writer:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

    bwStoreItems.Write("Floral Blouson Midi Dress");
    bwStoreItems.Write("Heathered Sweatpants");
    bwStoreItems.Write("Bellow Leather Knee-High Boots");
    bwStoreItems.Write("Pleated A-Line Skirt");
    bwStoreItems.Write("Long Sleeve Blouse");

    bwStoreItems.Close();
    fsStoreItems.Close();
}
</body>
</html>

Remember that if you provide a file name and path and that file exists already, it could be replaced, which may not be what you want. Therefore, before creating a file, you can first check whether it exists already or not.

Disposing of a Stream

The Stream class starts as follows:

public abstract class Stream : MarshalByRefObject, IDisposable

As you can see, this class implements the IDisposable interface. We saw that for an object of such a class, you can use the using operator to delimit the area where the object is used. In this case, when the compiler reaches the closing curly bracket, it would end (or close) its use and release the resources. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

    using (fsStoreItems)
    {
        bwStoreItems.Write("Floral Blouson Midi Dress");
        bwStoreItems.Write("Heathered Sweatpants");
        bwStoreItems.Write("Bellow Leather Knee-High Boots");
        bwStoreItems.Write("Pleated A-Line Skirt");
        bwStoreItems.Write("Long Sleeve Blouse");
    }
}
</body>
</html>

If the object is used only once, you can declare it in the parentheses of using(). Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    using (FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create))
    {
        BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

        bwStoreItems.Write("Floral Blouson Midi Dress");
        bwStoreItems.Write("Heathered Sweatpants");
        bwStoreItems.Write("Bellow Leather Knee-High Boots");
        bwStoreItems.Write("Pleated A-Line Skirt");
        bwStoreItems.Write("Long Sleeve Blouse");
    }
}
</body>
</html>

Binary Reading from a Stream

As opposed to writing to a stream, you may want to read existing data from it. Before doing this, you can first specify your intention to the streaming class using the FileMode enumeration. To support data reading, the FileMode enumeration provides other members as follows:

This can be done using a FileStream object as follows:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Open);
}
</body>
</html>

Once the stream is ready, you can get prepared to read data from it. To support this, the .NET Framework provides a class named BinaryReader defined in the System.IO namespace. This class provides two constructors. One of the constructors uses the following syntax:

public BinaryReader(Stream input);

This constructor takes as argument a Stream object, which could be a FileStream object. After declaring a FileStream variable using this constructor, you can read data from it. To do this, you can call one of its methods. The BinaryReader class provides an appropriate method for each primitive data type. Here are examples of calling the method:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Open);
    BinaryReader brStoreItems = new BinaryReader(fsStoreItems);

    <ul>
    	<li>@brStoreItems.ReadString()</li>
    	<li>@brStoreItems.ReadString()</li>
   	    <li>@brStoreItems.ReadString()</li>
    	<li>@brStoreItems.ReadString()</li>
    	<li>@brStoreItems.ReadString()</li>
    </ul>
}
</body>
</html>

As mentioned for data writing, after using the stream, you should close it to reclaim the resources it was using. This can be done by calling the Close() method. Here is an example using the mentioned methods:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Open);
    BinaryReader brStoreItems = new BinaryReader(fsStoreItems);

    . . .
 
    brStoreItems.Close();
    fsStoreItems.Close();
}
</body>
</html>

Alternatively, you can apply the using() operator to indicate the sphere of influence of the object.

Introduction to the File as an Object

Overview

To support files as objects, the .NET Framework provides a class named File. This static class is equipped with various types of (static) methods to create, save, open, copy, move, delete, or check the existence of a file.

File Existence

The File class makes it possible to check the existence of the file you want to use. For example, if you are creating a new file, you may want to make sure it doesn't exist already because if you try to create a file that exists already, the existing file may first be deleted before the new file is created. This could lead to unpredictable results. On the other hand, if you are trying to open a file, you should first make sure the file exists, otherwise you may receive an error.

To let you check the existence of a file, the File class is equipped with a method named Exists. Its syntax is:

public static bool Exists(string path);

If you provide only the name of the file, if the file exists, the method returns true. If the file cannot be found, the method returns false. Here is an example of calling this method:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems4";

    if(File.Exists(strStoreItems))
    {
        <p>The file exists already.</p>
    }
    else
    {
        using (FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create))
        {
            BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

            bwStoreItems.Write("Floral Blouson Midi Dress");
            bwStoreItems.Write("Heathered Sweatpants");
            bwStoreItems.Write("Bellow Leather Knee-High Boots");
            bwStoreItems.Write("Pleated A-Line Skirt");
            bwStoreItems.Write("Long Sleeve Blouse");
        }
    }
}
</body>
</html>

Of course, you can also check whether the file doesn't exist already. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems4";

    if(!(File.Exists(strStoreItems)))
    {
        using (FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create))
        {
            BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

            bwStoreItems.Write("Floral Blouson Midi Dress");
            bwStoreItems.Write("Heathered Sweatpants");
            bwStoreItems.Write("Bellow Leather Knee-High Boots");
            bwStoreItems.Write("Pleated A-Line Skirt");
            bwStoreItems.Write("Long Sleeve Blouse");
        }
    }
    else
    {
        <p>The file exists already.</p>
    }
}
</body>
</html>

Writing Text to a File

To provide general means of writing text to a file, the .NET Framework provides an abstract class named TextWriter.

public abstract class TextWriter : MarshalByRefObject, IDisposable

This class is equipped with an overloaded method named Write that provides a version for each primitive type.

To make it possible to specify the text to write, the .NET Framework provides a class named StreamWriter. This class is derived from TextWriter where it inherits the necessary methods:

public class StreamWriter : System.IO.TextWriter

Creating a Text File

To allow you to create a text file, the File class is equipped with a method named CreateText. Its syntax is:

public static StreamWriter CreateText(string path);

This method returns a StreamWriter object that you can use to write text to a file. Here are examples of continually calling this method to write some strings on the same line:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    if(!(File.Exists(strStoreItems)))
    {
        using (StreamWriter swStoreItems = File.CreateText(strStoreItems))
        {
            swStoreItems.Write("Floral Blouson Midi Dress");
            swStoreItems.Write("Heathered Sweatpants");
            swStoreItems.Write("Bellow Leather Knee-High Boots");
            swStoreItems.Write("Pleated A-Line Skirt");
            swStoreItems.Write("Long Sleeve Blouse");
        }
    }
    else
    {
        <p>The file exists already.</p>
    }
}
</body>
</html>

The TextWriter.Write() method writes a string on a line and keeps the caret on that line. To let you interrupt the writing and move to the next, the TextWriter class provides a method named WriteLine that too is overloaded with a version for each primitive type. Here are examples of calling this method to write some strings on different lines:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\Department Store\StoreItems";

    if(!(File.Exists(strStoreItems)))
    {
        using (StreamWriter swStoreItems = File.CreateText(strStoreItems))
        {
            swStoreItems.WriteLine("Floral Blouson Midi Dress");
            swStoreItems.WriteLine("Heathered Sweatpants");
            swStoreItems.WriteLine("Bellow Leather Knee-High Boots");
            swStoreItems.WriteLine("Pleated A-Line Skirt");
            swStoreItems.WriteLine("Long Sleeve Blouse");
        }
    }
    else
    {
        <p>The file exists already.</p>
    }
}
</body>
</html>

Since the File.CreateText() method returns an object derived from a TextWriter-derived, you can as well get a base object from it and use it. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Social Science: Philosophy</title>
</head>
<body>
    @{
        string strPhilosophy = @"C:\Social Studies\Philosophy";

        if (!(File.Exists(strPhilosophy)))
        {
            using (TextWriter twPhilosophy = File.CreateText(strPhilosophy))
            {
                twPhilosophy.WriteLine("Ethics");
                twPhilosophy.WriteLine("Aesthetics");
                twPhilosophy.WriteLine("Metaphysics");
                twPhilosophy.WriteLine("Epistemology");
            }
        }
        else
        {
            <p>The file exists already.</p>
        }
    }
</body>
</html>

Reading a Text File

To provide general means of reading text from a file, the .NET Framework provides an abstract class named TextReader:

public abstract class TextReader : MarshalByRefObject, IDisposable

This class is equipped with method to read text. Its method named Read can read text on the first line and keep the caret there. To let you move the caret to the next line, the class is equipped with a method named ReadLine that reads a line of text and moves to the next line.

To support the means of reading text from a file object, the .NET Framework provides a class named StreamReader. This class is derived from TextReader:

public class StreamWriter : System.IO.TextWriter

Here are examples of calling this method:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems6";

    if (File.Exists(strStoreItems))
    {
        using(StreamReader srStoreItems = new StreamReader(strStoreItems))
        {
            <ul>
                <li>@srStoreItems.ReadLine()</li>
                <li>@srStoreItems.ReadLine()</li>
                <li>@srStoreItems.ReadLine()</li>
                <li>@srStoreItems.ReadLine()</li>
                <li>@srStoreItems.ReadLine()</li>
            </ul>
        }
    }
    else
    {
        <p>The file exists already.</p>
    }
}
</body>
</html>

Exception Handling in File Processing

Finally Freeing the Resources of File Processing

As mentioned previously, when you create a stream, the operating system must allocate resources for its file processing operations. When the streaming is over, the resources should be freed. We saw that this can be done by calling the Close() method of the variable that was using resources.

During file processing, many things can go wrong. For this reason, the creation and/or management of streams should be performed in a try block to handle exceptions. Besides actually handling exceptions, the C# language provides a special keyword, named finally, that can be used to free resources.

The finally keyword is used to create a section of an exception. Like a catch clause, a finally block cannot exist by itself. It can be created following a try section. The formula to follow is:

try
{
}
finally
{
}

Based on this, the finally section has a body of its own, delimited by its curly brackets. Like a catch clause, the finally section is created after the try section. Unlike the catch keyword, the finally block never has parentheses and never takes arguments. Unlike a catch clause, the finally section is always executed. Because the finally clause always gets executed, you can include any type of code in it but it is usually appropriate to free the resources that were allocated earlier. Here is an example:

<!DOCTYPE html>
<html>
<head>
    <title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Create);
    BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

    try
    {
        bwStoreItems.Write("Floral Blouson Midi Dress");
        bwStoreItems.Write("Heathered Sweatpants");
        bwStoreItems.Write("Bellow Leather Knee-High Boots");
        bwStoreItems.Write("Pleated A-Line Skirt");
        bwStoreItems.Write("Long Sleeve Blouse");
    }
    finally
    {
        bwStoreItems.Close();
        fsStoreItems.Close();
    }
}
</body>
</html>

In the same way, you can use a finally section to free resources used when reading from a stream. Here is an example:

<!DOCTYPE html>
<html>
<head>
    <title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems6";

    FileStream fsStoreItems = new FileStream(strStoreItems, FileMode.Open);
    BinaryReader brStoreItems = new BinaryReader(fsStoreItems);
}

@try{
    <ul>
        <li>@brStoreItems.ReadString()</li>
        <li>@brStoreItems.ReadString()</li>
        <li>@brStoreItems.ReadString()</li>
        <li>@brStoreItems.ReadString()</li>
        <li>@brStoreItems.ReadString()</li>
    </ul>
}
finally
{
    brStoreItems.Close();
    fsStoreItems.Close();
}
</body>
</html>

Of course, since the whole block of code starts with a try section, it is used for exception handling. This means that you can add the necessary and appropriate catch section(s) but you don't have to.

.NET Framework Exception Handling for File Processing

The .NET Framework provides various exception-oriented classes to deal with almost any type of exception:

FileNotFoundException: The exception thrown when a file has not been found is of type FileNotFoundException.

IOException: As mentioned already, during file processing, anything could go wrong. If you don't know what caused an error, you can throw the IOException exception.

Introduction to File Information

File System Rules

A file system is a set of rules that the files used in an operating system must follow. To lay a general foundation for file system rules, the .NET Framework provides an abstract class named FileSystemInfo. This class contains the primary characteristics of a file.

File Information

As a computer object, a file holds many pieces of information that can be valuable. To provide such information, the .NET Framework provides a sealed class named FileInfo. This class is derived from FileSystemInfo. The FileInfo class is equipped with one constructor. Its syntax is:

public FileInfo(string fileName);

This method takes a string that indicates the file.

Creating a Text File

To allow you to create a text-based file, the FileInfo class is equipped with a method named CreateText. Its syntax is:

public System.IO.StreamWriter CreateTeext();

This method doesn't take an argument but produces a StreamWriter object that we saw already. You can use that object to write the desired value(s) to a file. Here are examples:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStudiesFile = @"C:\\Studies\\Social Science";
    FileInfo fiStudies = new FileInfo(strStudiesFile);

    using (StreamWriter swStudies = fiStudies.CreateText())
    {
        swStudies.WriteLine("History");
        swStudies.WriteLine("Sociology");
        swStudies.WriteLine("Geography");
        swStudies.WriteLine("Economics");
        swStudies.WriteLine("Psychology");
        swStudies.WriteLine("Linguistics");
        swStudies.WriteLine("Anthropology");
        swStudies.WriteLine("Political Science");
    }
}
</body>
</html>

Opening a Text File

One of the important operations performed on a file is to open it, for any reason. To support this operation, the FileInfo class is equipped with a method named OpenText. Its syntax is:

public System.IO.StreamReader OpenText();

As you can see, this method produces a StreamReader object. You can use that object to read values from the text of a FileInfo object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    string strStoreItems = @"C:\\Department Store\\StoreItems6";

    if (fiStoreItems.Exists == true)
    {
        StreamReader srStoreItems = fiStoreItems.OpenText();

        <ul>
            <li>@srStoreItems.ReadLine()</li>
            <li>@srStoreItems.ReadLine()</li>
            <li>@srStoreItems.ReadLine()</li>
            <li>@srStoreItems.ReadLine()</li>
            <li>@srStoreItems.ReadLine()</li>
        </ul>

        srStoreItems.Close();
    }
}
</body>
</html>

Introduction to the Characteristics of a File

A file as a computer object holds many characteristics. Many operating system operations can be performed on a file. Although many operations are available as we are going to review, you should not make them available to the visitors of your webpages.

The Directory of a File

Introduction

A directory is a section of a medium used to hold a file or a group of files. To support directories, the .NET Framework provides a static class named Directory. Additionally, the .NET Framework provides a class named DirectoryInfo. It is derived from the FileSystemInfo abstract class.

Creating a Directory

To let you create a directory, the Directory class is equipped with a method named CreateDirectory. It is overloaded with two versions. One of the versions uses the following syntax:

public static DirectoryInfo CreateDirectry(string path);

This method takes as argument the (complete) path of the desired directory. Here is an example:

E:\Programs\Business Orders\Customer Information

When this method is called:

The Directory.CreateDirectory() method returns a DirectoryInfo object that you can use as you see fit.

The Path to a File

The location of a file is referred to as its path or directory. The FileInfo class represents this path with a property named DirectoryName.

Besides the FileInfo.Directoryname, to let you know the full path to a file, the FileSystemInfo class is equipped with a property named FullName.

Mapping the Path to a File

To assist you in specifying the location of a file, the Server class of the webserver (Microsoft IIS) provides a method named MapPath. The HttpServerUtility class provides that method too. The MapPath() method takes a string that represents a file.

To use the Server..MapPath() method, you can declare a string variable to indicate the file, pass it to the Server.MapPath() method, and assign the method call to the variable used for the file.

To indicate an item located at the root of the website, pass the argument as a tilde "~". Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Exercise</title>
</head>
<body>
<h1>Exercise</h1>

@{
    string fileName = Server.MapPath("~");
}
</body>
</html>

If the file you want to access is located at the root, specify its name (and extension) after the tilde. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{ 
    string fileName = Server.MapPath("~/Employees.spr");
}
</body>
</html>

You can also declare the variable using the var or the dynamic keyword. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Department Store</title>
</head>
<body>
@{
    var strCustomers = Server.MapPath("~/Customers.cst");
    string strEmployees = Server.MapPath("~/Employees.spr");
    dynamic strStoreItems = Server.MapPath("~/StoreItems.sti");
}
</body>
</html>

Normally, you should refrain from creating files at the root of your website.

The Application Data Storage

A file can be located anywhere in a drive, such as the root of a hard drive. For security and management reasons, you should not allow your visitors to put files just anywhere. When a folder is necessary, you should (manually) create it yourself and then make it available.

If you create a folder in the root of your project, to specify its location in the Server.MapPath() folder, after the tilde, type a forward slash / followed by the name of the folder. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Exercise</title>
</head>
<body>
<h1>Exercise</h1>

@{
    string directory = Server.MapPath("~/Department Store");
}
</body>
</html>

Of course, if a file you want to use is located in the folder, after the name of the folder, type / followed by the name (and extension) of the file. In the same way, if you are trying to access a folder inside the top folder, separate the folder and subfolder(s) by forward slashes.

To assist you in managing data created and stored in your website, Microsoft Visual Studio proposes a special folder named App_Data. If you create an ASP.NET project using the MVC icon in the New ASP.NET Web Application dialog box, Microsoft Visual Studio would automatically create and add the App_Data folder to the project. If you create the project as Empty, to add the folder, in the Solution Explorer:

  • Right-click the name of the project, position the mouse on Add, then Add ASP.NET Folder, and click App_Data
  • Click the name of the project to select it. On the main menu, click Project, position the mouse on Add ASP.NET Folder, and click App_Data
  • If a file is, or will be, stored in the App_Data folder, indicate it. Here are examples:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        string strStoreItems = Server.MapPath("~/App_Data/StoreItems.sti");
        var    strCustomers = Server.MapPath("~/App_Data/Customers.cst");
        dynamic strEmployees = Server.MapPath("~/App_Data/StoreItems.sti");
    }
    </body>
    </html>

    You can use this method to specify the path of a directory you want to create. Here is an example:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{ 
        Directory.CreateDirectory(Server.MapPath("~/App_Data/Department Store"));
    }
    </body>
    </html>

    Checking for a Directory Existence

    Before using or creating a directory, you can first check if it exists. This is because, if a directory already exists in the location where you want to create it, you would be prevented from creating one with the same name. In the same way, if you just decide to directly use a directory that doesn't exist, the operation you want to perform may fail.

    Before using or creating a directory, to first check whether it exists or not, you can call the Directory.Exists() Boolean method. Its syntax is:

    public static bool Exists(string path);

    This method receives the (complete) path of the directory. If the path exists, the method returns true. If the directory doesn't exist, the method returns false.

    Introduction to Files

    The Name of a File

    The primary characteristic of a file is its name, which you must provide when you create a file. As we have done so far, to specify the name of a file, you can declare a variable of type string and assign the name of the file to it. The name can be in one character, one word, or many words. To let you get the name of a file that you are reviewing or opening, the FileInfo class is equipped with a property named Name.

    The Extension of a File

    Various types of files exist in a computer and in a website. One way they are distinct or grouped is trough one or more symbols at their end. When creating a file, to specify its extension, after the name of the document, type a period, followed by one or more letters. Here is an example:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{ 
        string strStoreItems = Server.MapPath("~/App_Data/Department Store/Store Items.sti");
    
        using (StreamWriter swStoreItems = File.CreateText(strStoreItems))
        {
            swStoreItems.WriteLine("Crepe Pencil Skirt");
            swStoreItems.WriteLine("Petals Button-Down Shirt");
            swStoreItems.WriteLine("Flip-Lock Shoulder Bag");
        }
    }
    </body>
    </html>

    Normally, you can provide any extension you want. You as the programmer will decide what extension you want to apply to your file. Some extensions should (must) be used for some types of files. For example, a text file should have the extension .txt. For some other types of files, you can use any extension you want.

    When you access a file or when a visitor opens one, to let you know the extension of that file, the FileSystemInfo class is equipped with a property named Extension.

    The Location of a File

    The path of a file is the location where it resides and its name. Normally, when you are creating a new file, you must provide its path. If a file exists already, to let you know its path, the FileSystemInfo class is equipped with a property named FullName.

    The Size of a File

    To let you get the size of a file (in terms of bits, kilobits, or kilobytes), the FileInfo class is quipped with a property named Length. Here is an example of accessing it:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        span class="codered">FileInfo fiStoreItems = new FileInfo(Server.MapPath("~/App_Data/StoreItems.txt"));
    }
    
    <p>File Size: @span class="codered">fiStoreItems.Length</p>
    </body>
    </html>

    The Group of Files of a Directory

    To let you get the files stored in a directory, the DirectoryInfo class provides a method named GetFiles. This method is overloaded with three versions. One of the versions doesn't take an argument. Its syntax is:

    public System.IO.FileInfo[] GetFiles();

    This method returns an array of files stored in the directory file that called it. This version that doesn't take an argument would get the list of files in the current directory. Here is an example of calling this method:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        DirectoryInfo diStoreItems = new DirectoryInfo(Server.MapPath("~/App_Data/Department Store"));
    }
    
    <ul>
    @for (int i = 0; i < diStoreItems.GetFiles().Length; i++)
    {
        <li>@diStoreItems.GetFiles()[i]</li>
    }
    </ul>
    
    </body>
    </html>

    The Attributes of a File

    Introduction

    Attributes are characteristics that apply to a file about what can be done or must be disallowed on it. The Attributes are primarily defined by, and in, the operating system, mostly when a file is created. You can control some aspects when creating a file. To assist you with this, the .NET Framework provides a few enumerations that are passed to the variable used to create the file.

    The Access to a File

    To perform an operation on a file, one of the options is to indicate the type of access that will be granted on the file. This access is specified using the FileAccess enumeration. To support file access, the FileStream class is equipped with the following constructor:

    public FileStream(string path, FileMode mode, FileAccess access);

    The members of the FileAccess enumeration are:

    Here is an example of apply the file access:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        string strQuotes = Server.MapPath("~/App_Data/Quotes.qts");
    
        FileStream fsQuotes = new FileStream(strQuotes, FileMode.Create, FileAccess.Write);
        BinaryWriter bwQuotes = new BinaryWriter(fsQuotes);
    
        using (fsQuotes)
        {
            bwQuotes.Write("There are known knowns. These are things we know that we know. " +
                           "There are known unknowns. That is to say, there are things that we " +
                           "know we don't know. But there are also unknown unknowns. " +
                           "There are things we don't know we don't know. - Donald Rumsfeld -");
        }
    }
    </body>
    </html>

    File Sharing

    You may want to create a file that different people or visitors can access at the same time or you may make one file access another file to retrieve information. When an operation must be performed on a file, you may have to specify how a file can be shared. This is done through the FileShare enumeration. To support this characteristic, the FileStream is equipped with the following constructor:

    public FileStream(string path,
    		  FileMode mode,
    		  FileAccess access,
    		  FileShare share);

    The members of the FileShare enumeration are:

    Here is an example of apply the file access:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        string strQuotes = Server.MapPath("~/App_Data/Quotes.qts");
    
        FileStream fsQuotes = new FileStream(strQuotes, FileMode.Create, FileAccess.Write, FileShare.Write);
        BinaryWriter bwQuotes = new BinaryWriter(fsQuotes);
    
        using (fsQuotes)
        {
            bwQuotes.Write("There are known knowns. These are things we know that we know. " +
                           "There are known unknowns. That is to say, there are things that we " +
                           "know we don't know. But there are also unknown unknowns. " +
                           "There are things we don't know we don't know. - Donald Rumsfeld -");
        }
    }
    </body>
    </html>

    Getting the Attributes of a File

    When the user accesses or opens a file, to let you get its attributes, the FileSystemInfo class is equipped with a property named Attributes. This property produces a FileAttributes object. When you create or access a file, you can specify or change some of the attributes. To do this, you can a FileAttributes object and assign it to the FileSystemInfo.Attributes property.

    FileAttributes is an enumeration with the following members: Archive, Compressed, Device, Directory, Encrypted, Hidden, Normal, NotContentIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.

    The Date and Time a File Was Created

    As mentioned already, the operating system keeps track of the date and time a file was created. To let you find out what those date and time values are, the FileSystemInfo class is equipped with a property named CreationTime. This would be done as follows:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        FileInfo fiStoreItems = new FileInfo(Server.MapPath("~/App_Data/StoreItems.txt"));
        DateTime dtCreation = fiStoreItems.CreationTime;
    }
    
    @if (fiStoreItems.Exists == true)
    {
        <p>Date/Time File Created: @dtCreation.ToLongDateString()</p>
    }
    </body>
    </html>

    The Date and Time a File Was Last Accessed 

    To let you know the date and time that the file was last accessed, the FileSystemInfo class is equipped with a property named LastAccessTime. If you are interested to know the last date and time a file was modified, the FileSystemInfo provides a property named LastWriteTime.

    Routine Operations on Files

    Deleting a File

    If you have an existing file you don't need anymore, you can delete it. To let you perform this operation, the Filee class is equipped with a method named Delete. Its syntax is:

    public static void Delete(string path);

    In the same way, to support file deletion, the FileInfo class is equipped with a method named Delete. Its syntax is:

    public override void Delete();

    In both cases, pass the pass and name of the undesired file as argument. Here is an example:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Department Store</title>
    </head>
    <body>
    @{
        FileInfo fiStoreItems = new FileInfo(Server.MapPath("~/App_Data/StoreItems.txt"));
    
        if (fiStoreItems.Exists == true)
        {
            fiStoreItems.Delete();
        }
    }
    </body>
    </html>

    Obviously this is not the type of operation you should make available to your visitors.

    Copying a File

    You can make a copy of a file from one directory to another. To assist you with this, the FileInfo class is equipped with a method named CopyTo. It is overloaded with two versions. The first version has the following syntax:

    public FileInfo CopyTo(string destFileName);

    When calling this method, specify the path or directory that will be the destination of the copied file. Here is an example:

    @{
        var fleMembers = new FileInfo(Server.MapPath("~/App_Data/Reality.txt");
    
        if(fleMembers.Exists == true)
        {
            fleMembers.CopyTo(Server.MapPath("~/App_Data/FederalSomeDocument.txt"), Server.MapPath("~/App_Data/Federal.txt"));
        }
    }

    This too is not an operation your visitors need.

    When calling the first version of the FileInfo.CopyTo() method, if the file exists already, the operation would not continue. If you insist, you can overwrite the target file. To do this, you can use the second version of this method. Its syntax is:

    public FileInfo CopyTo(string destFileName, bool overwrite);

    The first argument is the same as that of the first version of the method. The second argument specifies what action to take if the file exists already in the target directory. If you want to overwrite it, pass the argument as true; otherwise, pass it as false.

    Moving a File

    Instead of copying, if you want, you can move the file from one directory to another. To help you perform this operation, the FileInfo class is equipped with a method named MoveTo. Its syntax is:

    public void MoveTo(string destFileName);

    The argument to this method is the same as that of the CopyTo() method. After executing this method, the FileInfo object would be moved to the destFileName path.


    Previous Copyright © 2008-2019, FunctionX Home