Overview of File Processing

Introduction

In a regular application, if we request information from a user, when the app is closed, all the information that the user typed is lost. This is because such information was only temporarily stored in the random-access memory (RAM) of the user'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:

public class Exercise
{
    public static void Main()
    {
        string fileName = "Employees";
    }
}

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

public class Exercise
{
    public static void Main()
    {
        var strCustomer = "Account927-004";
        string strEmployee = "EmplNbr248";
        dynamic strStoreItem = "BlackDress";
    }
}

The above declarations indicate that the file is, or will be, stored 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:

public class Exercise
{
    public static void Main()
    {
        var     strCustomer  = "C:\\Account927-004";
        dynamic strEmployees = "C:\\Human Resources\\EmplNbr248";
        string  strStoreItem = "C:\\General Inventory\\Store Items\\BlackDress";
    }
}

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:

public class Exercise
{
    public static void Main()
    {
        var     strCustomer  = @"C:\Account927-004";
        dynamic strEmployees = @"C:\Human Resources\EmplNbr248";
        string  strStoreItem = @"C:\General Inventory\Store Items\BlackDress";
    }
}

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. This can be done as follows:

using System.IO;

public class Exercise
{
    public static void Main()
    {

    }
}

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 Stream or one of its derived classes, such as 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:

using System.IO;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\Department Store\StoreItems";

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

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:

using System.IO;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\Department Store\StoreItems";

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

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\Department Store\StoreItems";

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

        Title = "Department Store";
    
        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");
    }
}

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 class 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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\Department Store\StoreItems";

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

        Title = "Department Store";
    
        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();
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        public static int Main(string[] args)
        string strStoreItems = @"C:\Department Store\StoreItems";

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

        Title = "Department Store";
    
        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();
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

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

        Title = "Department Store";
    
        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");
        }
    }
}

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

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";
    
        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");
        }
    }
}

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:

using System.IO;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

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

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

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

        Title = "Department Store";

        BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

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

        Title = "Department Store";

        BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
        WriteLine(brStoreItems.ReadString());
 
        brStoreItems.Close();
    }
}

Alternatively, you can apply the using() operator to indicate the sphere of influence of the object. Here is an example:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

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

        Title = "Department Store";

        using (fsStoreItems)
        {
            BinaryWriter bwStoreItems = new BinaryWriter(fsStoreItems);

            WriteLine(brStoreItems.ReadString());
            WriteLine(brStoreItems.ReadString());
            WriteLine(brStoreItems.ReadString());
            WriteLine(brStoreItems.ReadString());
            WriteLine(brStoreItems.ReadString());
        }
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";

        if (File.Exists(strStoreItems))
        {
            WriteLine("The file exists already.");
        }
        else
        {
            using (Stream 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");
            }
        }
    }
}

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

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";

        if(!File.Exists(strStoreItems))
        {
            using (Stream 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
        {
            WriteLine("The file exists already.");
        }
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";

        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
        {
            WriteLine("The file exists already.");
        }
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";

        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
        {
            WriteLine("The file exists already.");
        }
    }
}

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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strPhilosophy = @"C:\Social Studies\Philosophy";

        Title = "Department Store";

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

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 methods 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:

using System.IO;
using static System.Console;

public class Exercise
{
    public static void Main()
    {
        string strStoreItems = @"C:\\Department Store\\StoreItems";

        Title = "Department Store";

        if (File.Exists(strStoreItems))
        {
            using (StreamReader srStoreItems = new StreamReader(strStoreItems))
            {
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
            }
        }
        else
        {
            WriteLine("The file exists already.");
        }
    }
}

Exception Handling in File Processing

Finally Freeing the Resources of File Processing

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:

using System.IO;
using static System.Console;

namespace Exercise1
{
    public class Exercise
    {
        public static int Main()
        {
            string strStoreItems = @"C:\\Department Store\\StoreItems1";

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

            Title = "Department Store";
            
            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();
            }

            return 0;
        }
    }
}

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

using System.IO;
using static System.Console;

namespace Exercise1
{
    public class Exercise
    {
        public static int Main()
        {
            string strStoreItems = @"C:\\Department Store\\StoreItems";

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

            Title = "Department Store";
            WriteLine("Department Store");
            WriteLine("--------------------------------");

            try
            {
                WriteLine(brStoreItems.ReadString());
                WriteLine(brStoreItems.ReadString());
                WriteLine(brStoreItems.ReadString());
                WriteLine(brStoreItems.ReadString());
                WriteLine(brStoreItems.ReadString());
            }
            finally
            {
                brStoreItems.Close();
                fsStoreItems.Close();
            }

            WriteLine("================================");
            return 0;
        }
    }
}

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

In the previous lesson as our introduction to file processing, we behaved as if everything was alright. Unfortunately, file processing can be very strict in its assignments. Based on this, the .NET Framework provides various Exception-oriented classes to deal with almost any type of exception you can think of.

One of the most important aspects of file processing is the name of the file that will be dealt with. In some cases you can provide this name to the application or document. In some other cases, you would let the user specify the name of the path. Regardless of how the name of the file would be provided to the operating system, when this name is acted upon, the compiler is asked to work on the file. If the file doesn't exist, the operation cannot be carried. Furthermore, the compiler would throw an error. There are many other exceptions that can be thrown as a result of something going bad during file processing:

FileNotFoundException: The exception thrown when a file has not been found is of type FileNotFoundException. Here is an example of handling it:

using System;
using System.IO;

public class Program
{
    static int Main(string[] args)
    {
/*      var Filename = "Members.clb";
        var fstPersons = 
            new FileStream(Filename, FileMode.Create);
        var wrtPersons = new BinaryWriter(fstPersons);
        
        try 
        {
            wrtPersons.Write("James Bloch");
            wrtPersons.Write("Catherina Wallace");
            wrtPersons.Write("Bruce Lamont");
            wrtPersons.Write("Douglas Truth");
        }
        finally
        {
            wrtPersons.Close();
            fstPersons.Close();
        }*/


        var strLine = "";
        var Filename = "Members.clc";

        try
        {
            var fstMembers =
                new FileStream(Filename, FileMode.Open);
            var rdrMembers = new BinaryReader(fstMembers);

            try
            {
                strLine = rdrMembers.ReadString();
                Console.WriteLine(strLine);
                strLine = rdrMembers.ReadString();
                Console.WriteLine(strLine);
                strLine = rdrMembers.ReadString();
                Console.WriteLine(strLine);
                strLine = rdrMembers.ReadString();
                Console.WriteLine(strLine);
            }
            finally
            {
                rdrMembers.Close();
                fstMembers.Close();
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.Write("Error: " + ex.Message);
            Console.WriteLine(" May be the file doesn't exist " +
                              "or you typed it wrong!");
        }

        return 0;
    }
}

Here is an example of what this would produce:

Error: Could not find file 'C:\Documents and Settings\Administrator\Local 
Settings\Application Data\Temporary 
Projects\ConsoleApplication1\bin\Release\Members.clc'. 
May be the file doesn't exist or you typed it wrong!
Press any key to continue . . .

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 CreateText();

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:

using System.IO;
using static System.Console;

namespace Exercise1
{
    public class Exercise
    {
        public static int Main()
        {
            string strStudiesFile = @"C:\\Social Studies\\Social Science1";
            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");
            }

            return 0;
        }
    }
}

File Existence

When you call the FileInfo.Create() or the FileInfo.CreateText() method, if the file passed as argument, or as the file in the path of the argument, exists already, it would be deleted and a new one would be created with the same name. This can cause the right file to be deleted. Therefore, before creating a file, you may need to check whether it exists already. To do this, you can check the value of the Boolean FileInfo.Exists property. This property holds a true value if the file exists already and it holds a false value if the file doesn't exist or it doesn't exist in the path.

Here is an example of checking the existence of a file:

using System;
using System.IO;

public class Program
{
    static int Main(string[] args)
    {
        var fleMembers = new FileInfo("First.txt");

        if (fleMembers.Exists == true)
            return 0;
        else
            fleMembers.Create();

        return 0;
    }
}

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:

using System.IO;
using static System.Console;

namespace Exercise1
{
    public class Exercise
    {
        public static int Main()
        {
            string strStoreItems = @"C:\\Department Store\\StoreItems";
            FileInfo fiStoreItems = new FileInfo(strStoreItems);

            Title = "Department Store";
            WriteLine("Department Store");
            WriteLine("--------------------------------");

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

                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());
                WriteLine(srStoreItems.ReadLine());

                srStoreItems.Close();
            }

            WriteLine("================================");
            return 0;
        }
    }
}

Appending to a File

You may have created a text-based file and written to it. If you open such a file and find out that a piece of information is missing, you can add that information to the end of the file. To do this, you can call the FileInfo.AppenText() method. Its syntax is:

public StreamWriter AppendText();

When calling this method, you can retrieve the StreamWriter object that it returns, then use that object to add new information to the file. Here is an example:

using System;

using System.IO;

namespace WattsALoan2
{
    public class Program
    {
        private static void CreateNewEmployee()
        {
            string employeeNumber, employeeName;
            FileInfo fleEmployees = new FileInfo("Employees.txt");
            StreamWriter swrEmployees = null;

            // If the file exists already, then add the new employee to it
            if (fleEmployees.Exists == true)
                swrEmployees = fleEmployees.AppendText();
            else // Otherwise, create a new file
                swrEmployees = fleEmployees.CreateText();

            try
            {
                Console.WriteLine("Hiring New Employee");
                Console.Write("Enter Employee Number as 00-000: ");
                employeeNumber = Console.ReadLine();
                Console.Write("Enter Employee Name: ");
                employeeName = Console.ReadLine();

                swrEmployees.WriteLine(employeeNumber);
                swrEmployees.WriteLine(employeeName);

            }
            finally
            {
                swrEmployees.Flush();
                swrEmployees.Close();
            }
        }
    }
}

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.

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:

using System.IO;

namespace DepartmentStore
{
    public class Exercise
    {
        public static int Main()
        {
            string strStoreItems = "C:\\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");
            }

            return 0;
        }
    }
}

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:

using System.IO;
using static System.Console;

namespace DepartmentStore
{
    public class Exercise
    {
        public static int Main()
        {
            FileInfo fiStoreItems = new FileInfo("C:\\Department Store\\Store Items.sti");

            WriteLine("File Size: " + fiStoreItems.Length);
            WriteLine("=================================");

            return 0;
        }
    }
}

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:

using System.IO;
using static System.Console;

namespace DepartmentStore
{
    public class Exercise
    {
        public static int Main()
        {
            DirectoryInfo diStoreItems = new DirectoryInfo("C:\\Department Store");

            for (int i = 0; i < diStoreItems.GetFiles().Length; i++)
                WriteLine(diStoreItems.GetFiles()[i]);

            WriteLine("=================================");

            return 0;
        }
    }
}

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:

using System.IO;
using static System.Console;

namespace SocialStudies
{
    public class Exercise
    {
        public static int Main()
        {
            string strQuotes = ("C:\\Social Studies\\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 -");
            }

            WriteLine("=================================");

            return 0;
        }
    }
}

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:

using System.IO;
using static System.Console;

namespace SocialStudies
{
    public class Exercise
    {
        public static int Main()
        {
            string strQuotes = ("C:\\Social Studies\\Quotes1.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 -");
            }

            WriteLine("=================================");

            return 0;
        }
    }
}

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:

using System;
using System.IO;

namespace DepartmentStore
{
    public class Exercise
    {
        public static int Main()
        {
            FileInfo fiStoreItems = new FileInfo("C:\\Department Store\\StoreItems");
            DateTime dtCreation = fiStoreItems.CreationTime;

            if (fiStoreItems.Exists == true)
                Console.WriteLine("Date/Time File Created: " + dtCreation.ToLongDateString());

            Console.WriteLine("======================================");

            return 0;
        }
    }
}

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.


Previous Copyright © 2008-2019, FunctionX Next