Home

Introduction to File Processing

 

Overview of File Processing and Definitions

 

Introduction

A piece of information used in an application is primarily represented as a group of bits. So far, if we requested information from the user, when the application exited, we lost all information that the user had entered. This is because such information was only temporarily stored in the random access memory (RAM).

In some cases, you will want to "keep" information that the user has entered so you can make the information available the next time the user opens the application. In some other cases, whether you request information from the user or inherently provide it to the user, you may want different people working from different computers to use or share the same data. In these and other scenarios, you must store the information somewhere and retrieve it when necessary. This is the basis of file processing.

Files

A file is a series of bytes of data that are arranged in a particular manner to produce a usable document. For easy storage, location, and management, the bytes are stored on a medium such as a hard disc, a floppy disc, a compact disc, or any valid and supported type of storage. 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.

For greater management, files can be stored in a parent object called a directory or a folder. Since a file is a unit of storage and it stores information, it has a size, which is the number of bits it uses to store its values. To manage it, a file has a location also called a path that specifies where and/or how the file can be retrieved. Also, for better management, a file has attributes (characteristics) that indicate what can be done on the file or that provide specific information that the programmer or the operating system can use when dealing with the file.

Streams

File processing consists of creating, storing, and/or retrieving the contents of a file from a recognizable medium. For example, it is used to save word-processed files to a hard drive, to store a presentation on floppy disk, or to open a file from a CD-ROM. A stream is the technique or means of performing file processing. In order to manage files stored in a computer, each file must be able to 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 create a file, a user must first decide where it would be located: this is a requirement. A file can be located on the root drive. Alternatively, a file can be positioned inside of an existing folder. Based on security settings, a user may not be able to create a file just anywhere in the (file system of the) computer. Once the user has decided where the file would reside, there are various means of creating files that the users are trained to use. When creating a file, the user must give it a name following the rules of the operating system combined with those of the file system. The most fundamental piece of information a file must have is a name.

Once the user has created a file, whether the file is empty or not, the operating system assigns basic pieces of information to it. Once a file is created, it can be opened, updated, modified, renamed, etc.

Practical LearningPractical Learning: Introducing Streaming

  1. Start Microsoft Visual Studio
  2. To start a new application, on the main menu, click File -> New Project...
  3. In the middle list, click Windows Forms Application. Set the Name to ClarksvilleIceCream2
  4. Click OK
  5. In the Properties window, change the form's Text to Clarksville Ice Cream
  6. To create a new form, on the main menu, click Project -> Add New Item...
  7. In the Add New Item dialog box, Click Windows Form
  8. Change the name of the form to Calculation
  9. Click Add
  10. In the Components section of the Toolbox, click HelpProvider and click the form
  11. Design the new form as follows:
     
    Clarksville Ice Scream - Difference Calculation
    Control Name Text Additional Properties
    Label Label   Order Total:  
    TextBox TextBox txtOrderTotal 0.00 TextAlign: Right
    Modifier: Public
    Label Label   Amount Tended:  
    TextBox TextBox txtAmountTended 0.00 TextAlign: Right
    Button Button btnCalculate Calculate  
    Label Label   Difference:  
    TextBox TextBox txtDifference 0.00 TextAlign: Right
    Button Button btnClose Close  
    Form       FormBorderStyle: FixedDialog
    HelpButton: True
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskbar: False
  12. Using the Properties window, change the value of the HelpString On HelpProvider1 field as follows:
     
    Control HelpString On HelpProvider1
    txtOrderTotal This is the total amount of the current order
    txtAmountTended This is the amount the customer tended
    btnCalculate Click here to calculate the difference between the amount tended and the total price of the order
    txtDifference This displays the difference between the amount tended and the total of the order
    btnClose Click here to close the dialog box
  13. Double-click the Calculate button
  14. Return to the form and double-click the Close button
  15. Implement the Click events as follows:
    System::Void btnCalculate_Click(System::Object^  sender,
    	 System::EventArgs^  e)
    {
        double TotalOrder,
        AmountTended = 0.00,
        Difference;
    
        // Get the value of the total order. Actually, this value 
        // will be provided by the main form
        TotalOrder = double::Parse(txtOrderTotal->Text);
    	
        try 
        {
    	// The amount tended will be entered by the user
    	AmountTended = double::Parse(txtAmountTended->Text);
        }
        catch(FormatException ^)
        {
    	MessageBox::Show(L"The amount you entered is not "
    			 L"valid - Please try again!");
        }
    
        // Calculate the difference of both values, assuming 
        // that the amount tended is higher
        Difference = AmountTended - TotalOrder;
    
        // Display the result in the Difference text box
        txtDifference->Text = Difference.ToString();
    }
    
    System::Void btnClose_Click(System::Object^  sender, System::EventArgs^  e)
    {
        Close();
    }
  16. Close the Calculation.h window
  17. Close the Calculation.h [Design *] window
  18. When asked whether you want to save, click Yes
  19. Make sure the first form is displaying.
    On the Toolbox, click Dialogs
  20. Click SaveFileDialog SaveFileDialog and click the form
  21. In the Properties window, change the following values:
    (Name): dlgSaveFile
    DefaultExt: cic
    Filter: Clarksville Ice Cream Files (*.cic)|*.cic| All Files (*.*)|(*.*)
    Title: Save an Ice Cream Order
  22. In the Dialogs section of the Toolbox, click OpenFileDialog OpenFileDialog and click the form
  23. In the Properties window, change the following values:
    (Name): dlgOpenFile
    DefaultExt: cic
    Filter: Clarksville Ice Cream Files (*.cic)|*.cic| All Files (*.*)|(*.*)
    Title: Open an Ice Cream Order
  24. In the Menus & Toolbars section of the Toolbox, click the MenuStrip button and click the form
  25. While the menu strip is still selected, in the Properties window, click (Name) and type mnuMain
  26. Under the form, right-click mnuMain and click Insert Standard Items
     
    Clarksville Ice Cream
  27. On the form, click File
  28. In the Properties window, click (Name) and type mnuFile
  29. Under File, change the names of the menu items to mnuFileNew, mnuFileOpen, mnuFileSave, mnuFileSaveAs, mnuFilePrint, mnuFilePrintPreview, and mnuFileExit
  30. On the form, click Tools
  31. In the Properties window, click (Name) and type mnuHelp
  32. Under Help, change the names of the menu items to mnuHelpContents, mnuHelpIndex, and mnuHelpSearch
  33. In the Menus & Toolbars section of the Toolbox, click StatusStrip and click the form
  34. In the Properties window, click Items and click its ellipsis button
  35. In the Select Item and Add to List Below combo box, select StatusLabel and click Add
  36. On the right side, set the Text to Ready
  37. Click OK
  38. On the Toolbox, click ToolTip ToolTip and click the form
  39. On the Toolbox, click HelpProvider Help Provider and click the form
  40. In the Properties window, change its Name to hpvIceCream and click HelpNamespace
  41. Click the ellipsis button of the HelpNamespace property
  42. Select the IceCream.chm file
  43. Click Open
  44. On the main menu of the form, click Help and double-click Contents
  45. Implement the event as follows:
    private: System::Void mnuHelpContents_Click(System::Object ^  sender, 
    		  			    System::EventArgs ^  e)
    {
        Help::ShowHelp(this, hpIceCream->HelpNamespace);
    }
  46. Return to the form and double-click Index
  47. Implement the event as follows:
    private: System::Void mnuHelpIndex_Click(System::Object ^  sender,
    		  			 System::EventArgs ^  e)
    {
        Help::ShowHelpIndex(this, hpIceCream->HelpNamespace);
    }
  48. Return to the main form and double-click Search
  49. Implement the event as follows:
    private: System::Void menuItem6_Click(System::Object ^  sender,
    		  		      System::EventArgs ^  e)
    {
        Help::ShowHelp(this,
        		hpIceCream->HelpNamespace, HelpNavigator::Find, L"");
    }
  50. Return to the form and design it as follows:
     
    Clarksville Ice Cream: Form Design
    Control (Name) Text Additional Properties
    GroupBox GroupBox grpIceCreamOrder    
    Label Label   Order &Date:  
    TextBox TextBox txtOrderDate    
    Label Label   Order &Time:  
    TextBox TextBox txtOrderTime    
    Label Label   &Flavor:  
    TextBox TextBox txtFlavor    
    Label Label   &Container:  
    TextBox TextBox txtContainer    
    Label Label   &Ingredient:  
    TextBox TextBox txtIngredient    
    Label Label   &Scoops:  
    TextBox TextBox txtScoops 0 TextAlign: Right
    Label Label   &Order Total:  
    TextBox TextBox txtOrderTotal 0.00 TextAlign: Right
    GroupBox GroupBox grpCalculation    
    Button Button btnCalculate C&alculate  
    Button Button btnNewOrder New Or&der  
    Button Button btnMoneyChange &Money Change  
    Button Button btnClose C&lose  
  51. On the form, click each control and, in the Properties window, set its ToolTip On ToolTip property as follows:
     
    Control ToolTip On ToolTip1
    txtOrderDate Enter a value for a date (MM/DD/YYYY)
    txtOrderTime Enter a value for a time (00:00)
    txtFlavor Type the ice cream flavor the customer wants
    txtContainer Enter the type of container to hold the ice cream
    txtIngedient Enter the ingredient the customer wants. If the customer doesn't want any, type None
    txtScoops Enter the number of scoops (1, 2, or 3) to fill the container
    txtOrderTotal This displays the total amount of this order
    btnCalculate Click here to calculate the total of the order
    btnNewOrder Click here to reset the form
    btnMoneyChange Click here to calculate the change
    btnClose Click here to close the form
  52. Double-click the New Order button to access its Click event and implement it as follows:
    System::Void btnNewOrder_Click(System::Object^  sender, System::EventArgs^  e)
    {
        // If the user clicks New Order, we reset the form with the default values
        txtOrderDate->Text = DateTime::Today.ToLongDateString();
        txtOrderTime->Text = DateTime::Now.ToShortTimeString();
        txtFlavor->Text = L"Vanilla";
        txtContainer->Text = L"Cone";
        txtIngredient->Text = L"None";
        txtScoops->Text = L"0";
        txtOrderTotal->Text = L"0.00";
        btnMoneyChange->Enabled = false;
    }
  53. Return to the form and double-click the Calculate Total button
  54. Implement it as follows:
    System::Void btnCalculate_Click(System::Object^  sender, System::EventArgs^  e)
    {
        String ^ Container      = L"";
        double PriceContainer  = 0.00,
               PriceIngredient = 0.00,
               PriceScoops     = 0.00,
    	   OrderTotal      = 0.00;
        int NumberOfScoops     = 0;
    
        // First find out what container the customer requested
        Container = txtContainer->Text;
    
        // The price of a container depends on which one the customer selected
        if( Container->Equals(L"Cone") )
    	PriceContainer = 0.55;
        else if( Container->Equals(L"Cup") )
    	PriceContainer = 0.75;
        else
    	PriceContainer = 1.15;
    
        // If the customer selected an ingredient, which is not "None", add $.95
        if( !txtIngredient->Text->Equals("") )
    	PriceIngredient = 0.95;
            
        try 
        {
    	// Get the number of scoops
    	NumberOfScoops = int::Parse(txtScoops->Text);
    
    	if( NumberOfScoops == 2 )
    		PriceScoops = 2.55;
    	else if( NumberOfScoops == 3 )
    		PriceScoops = 3.25;
    	else
    		PriceScoops = 1.85;
        }
        catch(FormatException ^)
        {
    	MessageBox::Show(L"The value you entered for the scoops is not valid"
    	                 L"\nOnly natural numbers such as 1, 2, or 3 are allowed"
    	                 L"\nPlease try again");
        }
            
        // Make sure the user selected a flavor, 
        // otherwise, there is no reason to process an order
        if( !txtFlavor->Text->Equals(L"") )
    	OrderTotal = PriceScoops + PriceContainer + PriceIngredient;
    
        txtOrderTotal->Text = OrderTotal.ToString();
        btnMoneyChange->Enabled = true;
    }
  55. Return to the form and double-click the MoneyChange button
  56. In the top section of the file, include the Calculation.h header file:
    #pragma once
    
    #include "Calculation.h"
    
    namespace ClarksvilleIceCream2 {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
  57. Scroll down and implement its event as follows:
    System::Void btnMoneyChange_Click(System::Object^  sender, System::EventArgs^  e)
    {
        // Declare a variable for the Calculation form
        Calculation ^ dlgCalculation = gcnew Calculation;
    
        // Transfer the current value of the Order Total text 
        // box from the main form to the other form
        dlgCalculation->txtOrderTotal->Text = txtOrderTotal->Text;
        // Display the other form
        dlgCalculation->ShowDialog();
    }
  58. On the form, click the txtOrderDate text box
  59. In the Properties window, click the Events button Events and double-click MouseMove
  60. Return to the form
  61. In the same way, generate the MouseMove event of the txtOrderTime, the txtFlavor, the txtContainer, the txtIngredient, the txtScoops, and the txtOrderTotal text boxes
  62. Generate the MouseHover event for both group boxes
  63. Generate the MouseMove event for the form
  64. Implement the events as follows:
    System::Void txtOrderDate_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text =
     	 L"Specify the date this order was processed";
    }
    private: System::Void txtOrderTime_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text = 
    	L"Specify the time this order was processed";
    }
    private: System::Void txtFlavor_MouseMove(System::Object^  sender,
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text = 
    	L"Select the customer's desired flavor";
    }
    private: System::Void txtContainer_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text = 
    	L"Select the type of object that will contain the ice cream";
    }
    private: System::Void txtIngredient_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e) 
    {
        statusStrip1->Items[0]->Text = 
    	L"Select an ingredient to spice the ice cream";
    }
    private: System::Void txtScoops_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text = 
    	L"Select the number of scoops to fill the container";
    }
    private: System::Void txtOrderTotal_MouseMove(System::Object^  sender, 
    	System::Windows::Forms::MouseEventArgs^  e)
    {
        statusStrip1->Items[0]->Text = 
    	L"This displays the total of the order";
    }
    
    private: System::Void grpCalculation_MouseHover(System::Object^  sender,
    			 System::EventArgs^  e)
    {
    	 statusStrip1->Items[0]->Text = L"Ready";
    }
    		 
    private: System::Void grpIceCreamOrder_MouseHover(System::Object^  sender,
    			 System::EventArgs^  e)
    {
    	 statusStrip1->Items[0]->Text = L"Ready";
    }
    private: System::Void Form1_MouseMove(System::Object^  sender,
    	 System::Windows::Forms::MouseEventArgs^  e)
    {
    	 statusStrip1->Items[0]->Text = L"Ready";
    }
  65. To test the application, press F5
  66. After using it, close the form and return to your programming environment

Streaming Prerequisites

 

Introduction

To support file processing, the .NET Framework provides the System::IO namespace that contains many different classes to handle almost any type of file operation you may need to perform. Therefore, to perform file processing, you can include the System::IO namespace in your project.

The parent class of file processing is Stream. With Stream, you can store data to a stream or you can retrieve data from a stream. Stream is an abstract class, which means that you cannot use it to declare a variable in your application. As an abstract class, Stream is used as the parent of the classes that actually 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.

ApplicationPractical Learning: Referring to the System::IO Namespace

  1. Right-click the form and click View Code
  2. In the top section of the file, under the other using lines, type
    #pragma once
    
    #include "Calculation.h"
    
    namespace ClarksvilleIceCream2 {
    
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        using namespace System::IO;
    
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
        private:
            bool     fileIsNew;
            String ^ Filename;
    
        public:
    	Form1(void)
    	{
    		InitializeComponent();
    		//
    		//TODO: Add the constructor code here
    		//
    	}
    
    	. . . No Change
    	
        }
        
        private: System::Void btnNewOrder_Click(System::Object^  sender,
        					    System::EventArgs^  e)
        {
        // If the user clicks New Order, we reset the form with the default values
        	txtOrderDate->Text = DateTime::Today.ToLongDateString();
        	txtOrderTime->Text = DateTime::Now.ToShortTimeString();
        	txtFlavor->Text = L"Vanilla";
        	txtContainer->Text = L"Cone";
        	txtIngredient->Text = L"None";
        	txtScoops->Text = L"0";
        	txtOrderTotal->Text = L"0.00";
        	btnMoneyChange->Enabled = false;
                
            Filename = "";
            fileIsNew = true;
        }
    
        . . . No Change
    
  3. Display the form
  4. Double-click an occupied area of the form
  5. Implement the event as follows:
    private void ClarksvilleIceCream_Load(object sender, EventArgs e)
    {
        btnNewOrder_Click(sender, e);
    }
  6. Return to the form

The Name of a File

Before performing file processing, one of your early decisions will consist of specifying the type of operation you want the user to perform. For example, the user may want to create a brand new file, open an existing file, or perform a routine operation on a file. In all or most cases, whether you are creating a new file or manipulating an existing one, you must specify the name of the file. You can do this by declaring a String variable but, as we will learn later on, most classes used to create a stream can take a string that represents the file.

If you are creating a new file, there are certainly some rules you must observe. The name of a file follows the directives of the operating system. On MS DOS and Windows 3.X (that is, prior to Microsoft Windows 9X), the file had to use the 8.3 format. The actual name had to have a maximum of 8 characters with restrictions on the characters that could be used. The user also had to specify three characters after a period. The three characters, known as the file extension, were used by the operating system to classify the file. That was all necessary for those 8-bit and 16-bit operating systems. Various rules have changed. For example, the names of folders and files on Microsoft Windows >= 95 can have up to 255 characters. The extension of the file is mostly left to the judgment of the programmer but the files are still using extensions. Applications can also be configured to save different types of files; that is, files with different extensions.

Author Note At the time of this writing, the rules for file names for Microsoft Windows were on the MSDN web site at Windows Development\Windows Base Services\Files and I/O\SDK Documentation\Storage\Storage Overview\File Management\Creating, Deleting, and Maintaining Files\Naming a File (because it is a web site and not a book, its pages can change anytime).

Based on this, if you declare a String variable to hold the name of the file, you can simply initialize the variable with the necessary name and its extension. Here is an example:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Employees.spr";
}

The Path to a File

If you declare a string as above, the file will be created in the folder as the application. Otherwise, you can create your new file anywhere in the hard drive or on another medium. To do that, you must provide a complete path where the file will reside. A path is a string that specifies the drive (such as A:, C:, or D:, etc). The sections of a complete path are separated by a backslash. For example, a path can be made of a folder followed by the name of the file. An example would be

C:\Palermo.tde 

A path can also consist of a drive followed by the name of the folder in which the file will be created. Here is an example:

C:\Program Files\Palermo.tde

A path can also indicate that the file will be created in a folder that itself is inside of another folder. In this case, remember that the names of folders must be separated by backslashes.

We know that the backslash character is used to create or manage escape sequences and it can be included in a string value to make up an escape sequence. Because of this, every time you include a backslash in a string, the compiler thinks that you are trying to provide an escape sequence. In this case, if the combination of the backslash and the character that follows the backslash is not recognized as an escape sequence, you would get an error. To solve this problem, you have two alternatives. To indicate that the backslash must be considered as a character in its own right, you can double it. Here are examples:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{			
    String ^ NameOfFile = L"C:\\Documents and "
			  L"Settings\\Business Records\\Employees.spr";
}

In the same way, you can declare a String variable to represent the name of an existing file that you plan to use in your program. You can also represent its path.

When providing a path to the file, if the drive you specify doesn't exist or cannot be read, the compiler would consider that the file doesn't exist. If you provide folders that don't exist in the drive, the compiler would consider that the file doesn't exist. This also means that the compiler will not create the folder(s) (the .NET Framework provides all means to create a folder but you must ask the compiler to create it; simply specifying a folder that doesn't exist will not automatically create it, even if you are creating a new file). Therefore, it is your responsibility to make sure that either the file or the path to the file is valid. As we will see in the next section, the compiler can check the existence of a file or path.

 
 
 

The .NET Support for Files

 

Introduction

The primary support of a file as an object is provided by a .NET Framework class called File. This static class is equipped with various types of (static) member functions to create, save, open, copy, move, delete, or check the existence of a file.

File Existence

One of the valuable operations that the File class can perform is 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 compiler may first delete the old file before creating the new one. This could lead to unpredictable result, especially because such a file is not sent to the Recycle Bin. On the other hand, if you are trying to open a file, you should first make sure the file exists, otherwise the compiler will not be able to open a file it cannot find.

To check the existence of a file, the File class provides the Exists member function. Its syntax is:

public:
    static bool Exists(String ^path);

If you provide only the name of the file, the compiler would check it in the folder of the application. If you provide the path to the file, the compiler would check its drive, its folder(s) and the file itself. In both cases, if the file exists, the member function returns true. If the compiler cannot find the file, the member function returns false. It's important to know that if you provided a complete path to the file, any slight mistake would produce a false result.

File Creation

Besides checking the existence of the file, the File class can be used to create a new file. To support this operation, the File class is equipped with the Create() member function that is overloaded with two versions as follows:

public:
    static FileStream ^ Create(String ^ path);
public:
    static FileStream ^ Create(String ^ path, int buffersize);

In both cases, the File.Create() member function returns a Stream value, in this case a FileStream value. As the File.Create() member function indicates, it takes the name or path of the file as argument. If you know or want to specify the size, in bytes, of the file, you can use the second version.

To provide the same operation of creating a file, you can use the Open() member function of the File class. It is overloaded in three versions as follows:

public:
    static FileStream ^ Open(String ^ path, FileMode mode);
public:
    static FileStream ^ Open(String ^ path, 
			     FileMode mode, 
			     FileAccess access);
public:
   static FileStream Open(String ^ path,
                          FileMode mode,
       			  FileAccess access,
   			  FileShare share);

Access to a File

In order to perform an operation on a file, you must specify to the operating system how to proceed. One of the options you have is to indicate the type of access that will be granted on the file. This access is specified using the FileAccess enumerator. The members of the FileAccess enumerator are:

  • FileAccess::Write: New data can be written to the file
  • FileAccess.Read: Existing data can be read from the file
  • FileAccess.ReadWrite: Existing data can be read from the file and new data be written to the file

File Sharing

In standalone workstations, one person is usually able to access and open a file then perform the necessary operations on it. In networked computers, you may create a file that different people can access at the same time or you may make one file access another file to retrieve information. For example, suppose you create an application for a fast food restaurant that has two or more connected workstations and all workstations save their customers orders to a common file. In this case, you must make sure that any of the computers can access the file to save an order. An employee from one of these workstations must also be able to open the file to retrieve a customer order for any necessary reason. You can also create a situation where one file holds an inventory of the items of a store and another file holds the customers orders. Obviously one file would depend on another. Based on this, 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 enumerator.

The values of the FileShare enumerator are:

  • FileShare.Inheritable: Allows other file handles to inherit from this file
  • FileShare.None: The file cannot be shared
  • FileShare.Read: The file can be opened and read from
  • FileShare::Write: The file can be opened and written to
  • FileShare.ReadWrite: The file can be opened to write to it or read from it

The Mode of a File

Besides the access to the file, another option you will most likely specify to the operating system is referred to as the mode of a file. It is specified through the FileMode enumerator. The members of the FileMode Enumerator are:

  • FileMode.Append: If the file already exists, the new data will be added to its end. If the file doesn't exist, it will be created and the new data will be added to it
  • FileMode.Create: If the file already exists, it will be deleted and a new file with the same name will be created. If the file doesn't exist, then it will be created
  • FileMode.CreateNew: If the new already exists, the compiler will throw an error. If the file doesn't exist, it will be created
  • FileMode.Open: If the file exists, it will be opened. If the file doesn't exist, an error would be thrown
  • FileMode.OpenOrCreate: If the file already exists, it will be opened. If the file doesn't exist, it will be created
  • FileMode.Truncate: If the file already exists, its contents will be deleted completely but the file will be kept, allowing you to write new data to it. If the file doesn't exist, an error would be thrown

Fundamentals of File Streaming

 

Introduction

File streaming consists of performing one of the routine operations on a file, such as creating it or opening it. This basic operation can be performed using a class called FileStream. You can use a FileStream object to get a stream ready for processing. As one of the most complete classes of file processing of the .NET Framework, FileStream is equipped with all necessary properties and member functions. To use it, you must first declare a variable of it. The class is equipped with nine constructors.

One of the constructors (the second) of the FileStream class has the following syntax:

public:
    FileStream(String ^ path, FileMode mode);

This constructor takes as its first argument the name or the file or its path. The second argument specifies the type of operation to perform on the file. Here is an example:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile,
					       FileMode::Create);
}

Stream Writing

A streaming operation is typically used to create a stream. Once the stream is ready, you can write data to it. The writing operation is perform through various classes. One of these classes is 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. To do this, you would use one of the class' three constructors. One of its constructors (the second) has 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:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile,
					       FileMode::Create);
    BinaryWriter ^ wrtPersons = gcnew BinaryWriter(fstPersons);
}

Most classes that are used to add values to a stream are equipped with a member function called Write. This is also the case for the BinaryWriter class. This member function takes as argument the value that must be written to the stream. The member function 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:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile,
					       FileMode::Create);
    BinaryWriter ^ wrtPersons = gcnew BinaryWriter(fstPersons);

    wrtPersons->Write(txtPerson1->Text);
    wrtPersons->Write(txtPerson2->Text);
    wrtPersons->Write(txtPerson3->Text);
    wrtPersons->Write(txtPerson4->Text);

    txtPerson1->Text = L"";
    txtPerson2->Text = L"";
    txtPerson3->Text = L"";
    txtPerson4->Text = L"";
}

Stream Closing

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

To close a stream, you can can call the Close() member function of the class(es) you were using. Here are examples:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile,
					       FileMode::Create);
    BinaryWriter ^ wrtPersons = gcnew BinaryWriter(fstPersons);

    wrtPersons->Write(txtPerson1->Text);
    wrtPersons->Write(txtPerson2->Text);
    wrtPersons->Write(txtPerson3->Text);
    wrtPersons->Write(txtPerson4->Text);

    wrtPersons->Close();
    fstPersons->Close();

    txtPerson1->Text = L"";
    txtPerson2->Text = L"";
    txtPerson3->Text = L"";
    txtPerson4->Text = L"";
}

Practical LearningPractical Learning: Writing to a Stream

  1. On the form, click File and double-click the Save As menu item
  2. Implement the Click event as follows:
    System::Void mnuFileSaveAs_Click(System::Object^  sender, System::EventArgs^  e)
    {
        int scoops = 0;
        String ^ flavor = "";
        double total = 0.00;
        String ^ container = "";
        String ^ ingredient = "";
        DateTime dtOrderDate = DateTime::Today;
        DateTime dtOrderTime = DateTime::Today;
    
        // Get the values on the form
        try
        {
            dtOrderDate = DateTime::Parse(txtOrderDate->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order date",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        try
        {
            dtOrderTime = DateTime::Parse(txtOrderTime->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order time",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        flavor = txtFlavor->Text;
        container = txtContainer->Text;
        ingredient = txtIngredient->Text;
        scoops = int::Parse(txtScoops->Text);
        total = double::Parse(txtOrderTotal->Text);
    
        // In case the user did not yet calculate, do it now
        btnCalculate_Click(sender, e);
    
        try
        {
            // . . .  show the Save Dialog Box
            if( dlgSaveFile->ShowDialog() == 
            		System::Windows::Forms::DialogResult::OK)
            {
                // Get the file name that the user specified
                Filename = dlgSaveFile->FileName;
    
                // Save the values in the new file
                FileStream ^ stmIceCream = 
                		gcnew FileStream(Filename, FileMode::Create);
                BinaryWriter ^ bnwIceCream = gcnew BinaryWriter(stmIceCream);
    
                bnwIceCream->Write(dtOrderDate.ToShortDateString());
                bnwIceCream->Write(dtOrderTime.ToShortTimeString());
                bnwIceCream->Write(flavor);
                bnwIceCream->Write(container);
                bnwIceCream->Write(ingredient);
                bnwIceCream->Write(scoops.ToString());
                bnwIceCream->Write(total.ToString());
    
                bnwIceCream->Close();
                stmIceCream->Close();
    
                MessageBox::Show("The order has been saved.",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::OK,
                                MessageBoxIcon::Information);
            }
    
            // When the order has been saved,
            // ask the user whether to process a new order
            if( MessageBox::Show("Do you want to start a new ice cream order?",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::YesNo,
        MessageBoxIcon::Information) == System::Windows::Forms::DialogResult::Yes )
            {
                btnNewOrder_Click(sender, e);
            }
            else
            {
                fileIsNew = false;
            }
        }
        catch(Exception ^)
        {
            MessageBox::Show("Something went wrong. The order will not be saved",
                             "Clarksville Ice Cream",
                             MessageBoxButtons::OK,
                             MessageBoxIcon::Information);
        }
    }
  3. Return to the form
  4. Click File and double-click Save
  5. Implement the event as follows:
    System::Void mnuFileSave_Click(System::Object^  sender, System::EventArgs^  e)
    {
        int scoops = 0;
        String ^ flavor = "";
        double total = 0.00;
        String ^ container = "";
        String ^ ingredient = "";
        DateTime dtOrderDate = DateTime::Today;
        DateTime dtOrderTime = DateTime::Today;
    
        // Get the values on the form
        try
        {
            dtOrderDate = DateTime::Parse(txtOrderDate->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order date",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        try
        {
            dtOrderTime = DateTime::Parse(txtOrderTime->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order time",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        flavor = txtFlavor->Text;
        container = txtContainer->Text;
        ingredient = txtIngredient->Text;
        scoops = int::Parse(txtScoops->Text);
        total = double::Parse(txtOrderTotal->Text);
    
        // In case the user did not yet calculate, do it now
        btnCalculate_Click(sender, e);
    
        try
        {
            // If this is a new ice cream order, . . .
            if( fileIsNew == true )
            {
                // . . .  proceed as if the user clicked File -> Save As
                mnuFileSaveAs_Click(sender, e);
            }
    else // Otherwise, it looks like the user only wants to update an existing order
            {
                // Save the values in the new file
                FileStream ^ stmIceCream =
                		 gcnew FileStream(Filename, FileMode::Create);
                BinaryWriter ^ bnwIceCream = gcnew BinaryWriter(stmIceCream);
    
                bnwIceCream->Write(dtOrderDate.ToShortDateString());
                bnwIceCream->Write(dtOrderTime.ToShortTimeString());
                bnwIceCream->Write(flavor);
                bnwIceCream->Write(container);
                bnwIceCream->Write(ingredient);
                bnwIceCream->Write(scoops.ToString());
                bnwIceCream->Write(total.ToString());
    
                bnwIceCream->Close();
                stmIceCream->Close();
    
                MessageBox::Show("The order has been saved.",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::OK,
                                MessageBoxIcon::Information);
            }
        }
        catch(Exception ^)
        {
            MessageBox::Show("Something went wrong. The order will not be saved",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::OK,
                                MessageBoxIcon::Information);
        }
    }
  6. To execute the application, press F5
  7. Enter some values
  8. On the main menu, click File -> Save
  9. In the File Name of the dialog box, type 1010 and press Enter
  10. Click OK on the message box
  11. In the second message box, click Yes
  12. Enter the values as follows:
     
    Clarksville Ice Cream
  13. Click Calculate
     
    Clarksville Ice Cream
  14. On the main menu, click File -> Save
  15. In the File Name, type 1001 and click Save
  16. Click OK on the message box
  17. Click No on the second message box
  18. Close the form and return to your programming environment

Stream Reading

As opposed to writing to a stream, you may want to read existing data from it. Before doing this, you can first specify your intent to the streaming class using the FileMode enumerator. This can be done using the FileStream class as follows:

System::Void btnOpen_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile, FileMode::Open);
}

Once the stream is ready, you can get prepared to read data from it. To support this, you can use the BinaryReader class. This class provides two constructors. One of the constructors (the first) has the following syntax:

public:
    BinaryReader(Stream ^ input);

This constructor takes as argument a Stream value, 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 an appropriate member function. This class provides an appropriate member function for each primitive data type.

After using the stream, you should close it to reclaim the resources it was using. This is done by calling the Close() member function.

Here is an example of using the mentioned member functions:

System::Void btnOpen_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile, FileMode::Open);
    BinaryReader ^ rdrPersons = gcnew BinaryReader(fstPersons);
    String ^ strLine = nullptr;

    strLine = rdrPersons->ReadString();
    txtPerson1->Text = strLine;
    strLine = rdrPersons->ReadString();
    txtPerson2->Text = strLine;
    strLine = rdrPersons->ReadString();
    txtPerson3->Text = strLine;
    strLine = rdrPersons->ReadString();
    txtPerson4->Text = strLine;

    rdrPersons->Close();
    fstPersons->Close();
}

Practical LearningPractical Learning: Reading From a Stream

  1. On the form, click File and double-click the Open menu item
  2. Implement the event as follows:
    System::Void mnuFileOpen_Click(System::Object^  sender, System::EventArgs^  e)
    {
        if( dlgOpenFile->ShowDialog() == System::Windows::Forms::DialogResult::OK )
        {
            Filename = dlgOpenFile->FileName;
            String ^ orderDate;
            String ^ orderTime;
            String ^ selectedFlavor;
            String ^ selectedContainer;
            String ^ selectedIngredient;
            String ^ scoops;
            String ^ orderTotal;
    
            FileStream ^ stmIceCream = gcnew FileStream(Filename, FileMode::Open);
            BinaryReader ^ bnrIceCream = gcnew BinaryReader(stmIceCream);
    
            // If so, open it
            orderDate = bnrIceCream->ReadString();
            orderTime = bnrIceCream->ReadString();
            selectedFlavor = bnrIceCream->ReadString();
            selectedContainer = bnrIceCream->ReadString();
            selectedIngredient = bnrIceCream->ReadString();
            scoops = bnrIceCream->ReadString();
            orderTotal = bnrIceCream->ReadString();
    
            // And display it to the user
            txtOrderDate->Text = orderDate;
            txtOrderTime->Text = orderTime;
            txtFlavor->Text = selectedFlavor;
            txtContainer->Text = selectedContainer;
            txtIngredient->Text = selectedIngredient;
            txtScoops->Text = scoops;
            txtOrderTotal->Text = double::Parse(orderTotal).ToString("F");
    
            bnrIceCream->Close();
            stmIceCream->Close();
    
            fileIsNew = false;
        }
    }
  3. Return to the form
  4. Click File and double-click Exit
  5. Implement the event as follows:
    System::Void mnuFileExit_Click(System::Object^  sender, System::EventArgs^  e)
    {
        Close();
    }
  6. Execute the application to test it
  7. On the main meneu, click File -> Open...
  8. Locate and click a previously saved files
  9. Close the form and return to your programming environment
 

Exception Handling in File Processing

 

Finally

So far, to handle exceptions, we were using the try, catch, and throw keywords. These allowed us to perform normal assignments in a try section and then handle an exception, if any, in a catch block. We also mentioned that, when you create a stream, the operating system must allocate resources and dedicate them to the file processing operations. Additional resources may be provided for the object that is in charge of writing to, or reading from, the stream. We also saw that, when the streaming was over, we should free the resources and give them back to the operating system. To do this, we called the Close() member function of the variable that was using resources.

More than any other assignment, file processing is in prime need of exception handling. During file processing, there are many things that can go wrong. For this reason, the creation and/or management of streams should be performed in a try block to get ready to handle exceptions that would occur. Besides actually handling exceptions, you can use the finally keyword to free resources.

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

try
{
}
finally
{
}

Based on this:

  • The finally section has a body of its own, delimited by its curly brackets
  • Like catch, the finally section is created after the try section
  • Unlike catch, finally never has parentheses and never takes arguments
  • Unlike catch, 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 such as those used during streaming. Here is an example:

System::Void btnSave_Click(System::Object^  sender, System::EventArgs^  e)
{
    String ^ NameOfFile = L"Persons.spr";

    FileStream ^ fstPersons = gcnew FileStream(NameOfFile,
					       FileMode::Create);
    BinaryWriter ^ wrtPersons = gcnew BinaryWriter(fstPersons);

    try {
        wrtPersons->Write(txtPerson1->Text);
        wrtPersons->Write(txtPerson2->Text);
        wrtPersons->Write(txtPerson3->Text);
        wrtPersons->Write(txtPerson4->Text);
    }
    finally
    {
        wrtPersons->Close();
        fstPersons->Close();
    }

    txtPerson1->Text = L"";
    txtPerson2->Text = L"";
    txtPerson3->Text = L"";
    txtPerson4->Text = L"";
}

In the same way, you can use a finally section to free resources used when reading from a stream. 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.

Practical LearningPractical Learning: Finally Releasing Resources

  1. Right-click the form and click View Code
  2. Change the following two events:
    System::Void mnuFileSaveAs_Click(System::Object^  sender, System::EventArgs^  e)
    {
        int scoops = 0;
        String ^ flavor = "";
        double total = 0.00;
        String ^ container = "";
        String ^ ingredient = "";
        DateTime dtOrderDate = DateTime::Today;
        DateTime dtOrderTime = DateTime::Today;
    
        // Get the values on the form
        try
        {
            dtOrderDate = DateTime::Parse(txtOrderDate->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order date",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        try
        {
            dtOrderTime = DateTime::Parse(txtOrderTime->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order time",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        flavor = txtFlavor->Text;
        container = txtContainer->Text;
        ingredient = txtIngredient->Text;
        scoops = int::Parse(txtScoops->Text);
        total = double::Parse(txtOrderTotal->Text);
    
        // In case the user did not yet calculate, do it now
        btnCalculate_Click(sender, e);
    
        try
        {
            // . . .  show the Save Dialog Box
          if( dlgSaveFile->ShowDialog() == System::Windows::Forms::DialogResult::OK)
            {
                // Get the file name that the user specified
                Filename = dlgSaveFile->FileName;
    
                // Save the values in the new file
                FileStream ^ stmIceCream = 
                		gcnew FileStream(Filename, FileMode::Create);
                BinaryWriter ^ bnwIceCream = gcnew BinaryWriter(stmIceCream);
    
    	    try
    	    {
    		bnwIceCream->Write(dtOrderDate.ToShortDateString());
    		bnwIceCream->Write(dtOrderTime.ToShortTimeString());
    		bnwIceCream->Write(flavor);
    		bnwIceCream->Write(container);
    		bnwIceCream->Write(ingredient);
    		bnwIceCream->Write(scoops.ToString());
    		bnwIceCream->Write(total.ToString());
    				
    		MessageBox::Show("The order has been saved.",
                                     "Clarksville Ice Cream",
                                     MessageBoxButtons::OK,
                                     MessageBoxIcon::Information);
                }
                finally
                {
                    bnwIceCream->Close();
                    stmIceCream->Close();
    	    }
            }
    
      // When the order has been saved, ask the user whether to process a new order
            if( MessageBox::Show("Do you want to start a new ice cream order?",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::YesNo,
                                MessageBoxIcon::Information) == 
                                	System::Windows::Forms::DialogResult::Yes )
            {
                btnNewOrder_Click(sender, e);
            }
            else
            {
                fileIsNew = false;
            }
        }
        catch(Exception ^)
        {
            MessageBox::Show("Something went wrong. The order will not be saved",
                             "Clarksville Ice Cream",
                             MessageBoxButtons::OK,
                             MessageBoxIcon::Information);
        }
    }
    
    System::Void mnuFileSave_Click(System::Object^  sender, System::EventArgs^  e)
    {
        int scoops = 0;
        String ^ flavor = "";
        double total = 0.00;
        String ^ container = "";
        String ^ ingredient = "";
        DateTime dtOrderDate = DateTime::Today;
        DateTime dtOrderTime = DateTime::Today;
    
        // Get the values on the form
        try
        {
            dtOrderDate = DateTime::Parse(txtOrderDate->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order date",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        try
        {
            dtOrderTime = DateTime::Parse(txtOrderTime->Text);
        }
        catch(FormatException ^)
        {
            MessageBox::Show("Invalid order time",
                            "Clarksville Ice Cream",
                            MessageBoxButtons::OK,
                            MessageBoxIcon::Information);
        }
    
        flavor = txtFlavor->Text;
        container = txtContainer->Text;
        ingredient = txtIngredient->Text;
        scoops = int::Parse(txtScoops->Text);
        total = double::Parse(txtOrderTotal->Text);
    
        // In case the user did not yet calculate, do it now
        btnCalculate_Click(sender, e);
    
        try
        {
            // If this is a new ice cream order, . . .
            if( fileIsNew == true )
            {
                // . . .  proceed as if the user clicked File -> Save As
                mnuFileSaveAs_Click(sender, e);
            }
    else // Otherwise, it looks like the user only wants to update an existing order
            {
                // Save the values in the new file
                FileStream ^ stmIceCream =
                		gcnew FileStream(Filename, FileMode::Create);
                BinaryWriter ^ bnwIceCream = gcnew BinaryWriter(stmIceCream);
    
    	    try
    	    {
                    bnwIceCream->Write(dtOrderDate.ToShortDateString());
                    bnwIceCream->Write(dtOrderTime.ToShortTimeString());
                    bnwIceCream->Write(flavor);
                    bnwIceCream->Write(container);
                    bnwIceCream->Write(ingredient);
                    bnwIceCream->Write(scoops.ToString());
                    bnwIceCream->Write(total.ToString());
    
                    MessageBox::Show("The order has been saved.",
                                     "Clarksville Ice Cream",
                                     MessageBoxButtons::OK,
                                     MessageBoxIcon::Information);
    	    }
                finally
                {
                    bnwIceCream->Close();
                    stmIceCream->Close();
    	    }
            }
        }
        catch(Exception ^)
        {
            MessageBox::Show("Something went wrong. The order will not be saved",
                                "Clarksville Ice Cream",
                                MessageBoxButtons::OK,
                                MessageBoxIcon::Information);
        }
    }
    
    System::Void mnuFileOpen_Click(System::Object^  sender, System::EventArgs^  e)
    {
        if( dlgOpenFile->ShowDialog() == System::Windows::Forms::DialogResult::OK )
        {
            Filename = dlgOpenFile->FileName;
            String ^ orderDate;
            String ^ orderTime;
            String ^ selectedFlavor;
            String ^ selectedContainer;
            String ^ selectedIngredient;
            String ^ scoops;
            String ^ orderTotal;
    
    	FileStream ^ stmIceCream = nullptr;
            BinaryReader ^ bnrIceCream = nullptr;
    
            try
    	{
    	    stmIceCream = gcnew FileStream(Filename, FileMode::Open);
                bnrIceCream = gcnew BinaryReader(stmIceCream);
    
                // If so, open it
                orderDate = bnrIceCream->ReadString();
                orderTime = bnrIceCream->ReadString();
                selectedFlavor = bnrIceCream->ReadString();
                selectedContainer = bnrIceCream->ReadString();
                selectedIngredient = bnrIceCream->ReadString();
                scoops = bnrIceCream->ReadString();
                orderTotal = bnrIceCream->ReadString();
    
                // And display it to the user
                txtOrderDate->Text = orderDate;
                txtOrderTime->Text = orderTime;
                txtFlavor->Text = selectedFlavor;
                txtContainer->Text = selectedContainer;
                txtIngredient->Text = selectedIngredient;
                txtScoops->Text = scoops;
                txtOrderTotal->Text = double::Parse(orderTotal).ToString("F");
    
                fileIsNew = false;
    	}
            finally
            {
                bnrIceCream->Close();
                stmIceCream->Close();
    	}
        }
    }
  3. Execute the application and test it 
  4. Close the form

.NET Framework Exception Handling for File Processing

In the previous lesson of our introduction to file processing, we behaved as if everything was alright. Unfortunately, file processing can be very strict in its assignments. Fortunately, 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 will be 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 namespace System;
using namespace System::IO;

int main()
{
/*    String ^ NameOfFile = L"Members.clb";
	
    FileStream ^ fstPersons = gcnew FileStream(NameOfFile, FileMode::Create);
    BinaryWriter ^ wrtPersons = gcnew BinaryWriter(fstPersons);
        
    try 
    {
        wrtPersons->Write(L"James Bloch");
        wrtPersons->Write(L"Catherina Wallace");
        wrtPersons->Write(L"Bruce Lamont");
        wrtPersons->Write(L"Douglas Truth");
    }
    finally
    {
        wrtPersons->Close();
        fstPersons->Close();
    }*/
    
    String ^ NameOfFile = L"Members.clc";
    String ^ strLine = L"";

    try {
        FileStream ^ fstMembers =
                gcnew FileStream(NameOfFile, FileMode::Open);
        BinaryReader ^ rdrMembers = gcnew 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(L"Error: " + ex->Message);
        Console::WriteLine(L" May be the file doesn't exist " +
                           L"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
\My Documents\Visual Studio 2005\Projects\FileProcessing2
\FileProcessing2\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.

 
 
   
 

Home Copyright © 2010-2016, FunctionX