Home

Binary File Streaming

 

Introduction to File Streaming

File streaming consists of performing one of the routine operations on a file, such as creating 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 methods. 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 of the file or its path. The second argument specifies the type of operation to perform on the file. Here is an example:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";

	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
}
 

Practical LearningPractical Learning: Introducing File Streaming

  1. Create a new Windows Forms Application named ROSH1
  2. Design the form as follows:
     
    Red Oak High School - Form Design
    Control Name Text Other Properties
    GroupBox GroupBox   Identification  
    Label   Student Name:  
    TextBox txtStudentName    
    Label   School Year:  
    TextBox txtSchoolYear1    
    Label   /  
    TextBox txtSchoolYear2    
    GroupBox   Grades  
    Label   English:  
    TextBox txtEnglish 0.00  
    Label   History:  
    TextBox txtHistory 0.00  
    Label   Economics:  
    TextBox txtEconomics 0.00  
    Label   2nd Language:  
    TextBox txt2ndLanguage 0.00  
    Label   Geography:  
    TextBox txtGeography 0.00  
    Label   Arts:  
    TextBox txtArts 0.00  
    Label   Math:  
    TextBox txtMath 0.00  
    Label   Science:  
    TextBox txtScience 0.00  
    Label   Phys Educ:  
    TextBox txtPhysEduc 0.00  
    GroupBox   Grade Processing  
    Button btnCalculate Calculate  
    Label   Total:  
    TextBox txtTotal 0.00  
    Label   Average:  
    TextBox txtAverage 0.00  
    Button btnSave Save  
    Button btnOpen Open  
    Button btnClose Close  
  3. Double-click the Calculate button and implement its Click event as follows:
     
    System::Void btnCalculate_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 double english, history, economics, language2, geography, arts,
    	             math, science, physEduc, total, average;
    
    	 // Retrieve the value entered for each course
    	 try {
    		 english = this->txtEnglish->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the English course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    
    	 try {
    		 history = this->txtHistory->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the History course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 economics = this->txtEconomics->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the Economics course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 language2 = this->txt2ndLanguage->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	 MessageBox::Show(S"The value you entered for the 2nd Language course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 geography = this->txtGeography->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the Geography course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 arts = this->txtArts->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    		 MessageBox::Show(S"The value you entered for the Arts course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 math = this->txtMath->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the Math course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 science = this->txtScience->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    	MessageBox::Show(S"The value you entered for the Science course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    			 
    	 try {
    		 physEduc = this->txtPhysEduc->Text->ToDouble(0);
    	 }
    	 catch(FormatException *)
    	 {
    MessageBox::Show(S"The value you entered for the Physical Education course is not valid");
    		 this->txtEnglish->Focus();
    	 }
    
    	 // Calculate the total and the average
    	 total = english + history + economics + language2 +
    		     geography + arts + math + science + physEduc;
    	 average = total / 9;
    
    	 // Display the total and the average
    	 this->txtTotal->Text = total.ToString(S"F");
    	 this->txtAverage->Text = average.ToString(S"F");
    }
  4. Return to the form.
    Double-click the Close button and implement its event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  5. Execute the application to test it
 

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 performed 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 pointer. To do this, you would use one of the class' three constructors. The first constructor is the default, meaning it doesn't take an argument. The second constructor 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:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";

	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
	BinaryWriter *wrtPersons = new BinaryWriter(fstPersons);
}

Most classes that are used to add values to a stream are equipped with a method called Write. This is also the case for the BinaryWriter class. 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:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";

	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
	BinaryWriter *wrtPersons = new BinaryWriter(fstPersons);

	wrtPersons->Write(S"James Bloch");
	wrtPersons->Write(S"Catherina Wallace");
	wrtPersons->Write(S"Bruce Lamont");
	wrtPersons->Write(S"Douglas Truth");
}

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() method of the class(es) you were using. Here are examples:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";

	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
	BinaryWriter *wrtPersons = new BinaryWriter(fstPersons);

	wrtPersons->Write(S"James Bloch");
	wrtPersons->Write(S"Catherina Wallace");
	wrtPersons->Write(S"Bruce Lamont");
	wrtPersons->Write(S"Douglas Truth");

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

Practical LearningPractical Learning: Writing to a Stream

  1. Right-click the form and click View Code
  2. In the top section of the file, add the using namespace System::IO; line
     
    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;
  3. Display the form
    In the Toolbox, click the SaveFileDialog button SaveFileDialog and click the form
  4. In the Properties window, change the following properties
    DefaultExt: ros
    Filter: ROSH Students Grades (*.ros)|*.ros|All Files(*.*)|
    Title: Save Student Grades As
  5. On the form, double-click the Save button and implement its Click event as follows:
     
    System::Void btnSave_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 FileStream   *stmGrades = 0;
    	 BinaryWriter *bnwGrades = 0;
    
    	 // The information will not be saved if there is no name for the student
    	 if( this->txtStudentName->Text->Equals(S"") )
    	 {
    		 MessageBox::Show(S"The report cannot be saved without the name of the student");
    		 this->txtStudentName->Focus();
    		 return;
    	 }
    	 // The information will not be saved if there is no school year
    	 if( this->txtSchoolYear1->Text->Equals(S"") )
    	 {
    		 MessageBox::Show(S"The report cannot be saved without the school year");
    		 this->txtSchoolYear1->Focus();
    		 return;
    	 }
    	 if( this->txtSchoolYear2->Text->Equals(S"") )
    	 {
    		 MessageBox::Show(S"The report cannot be saved without the school year");
    		 this->txtSchoolYear2->Focus();
    		 return;
    	 }
    
    	 String *strFilename = String::Concat(this->txtStudentName->Text,
    		 this->txtSchoolYear1->Text, this->txtSchoolYear2->Text);
    	 this->saveFileDialog1->FileName = strFilename;
    	 // Display the Save dialog box
    	 // Find out if the user clicked OK or pressed Enter
    	 if( this->saveFileDialog1->ShowDialog() == DialogResult::OK )
    	 {
    		 // If the used provided a name that already exists for an existing file
    		 if( File::Exists(this->saveFileDialog1->FileName) )
    		 {
    			 // Find out if the user wants to replace the existing file
    System::Windows::Forms::DialogResult answer = MessageBox::Show(String::Concat(S"The student report exists already.",
    					                                                   S"Do you want to replace it?"),
    								   S"Save Student Report",
    								   MessageBoxButtons::YesNo);
    
    			 // If the user wants to replace it
    			 if( answer == DialogResult::Yes )
    			 {
    				 stmGrades = new FileStream(this->saveFileDialog1->FileName, FileMode::Create);
    				 bnwGrades = new BinaryWriter(stmGrades);
    
    				 // Then overwrite it
    				 bnwGrades->Write(this->txtStudentName->Text);
    				 bnwGrades->Write(this->txtSchoolYear1->Text);
    				 bnwGrades->Write(this->txtSchoolYear2->Text);
    				 bnwGrades->Write(this->txtEnglish->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtHistory->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtEconomics->Text->ToDouble(0));
    				 bnwGrades->Write(this->txt2ndLanguage->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtGeography->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtArts->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtMath->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtScience->Text->ToDouble(0));
    				 bnwGrades->Write(this->txtPhysEduc->Text->ToDouble(0));
    
    				bnwGrades->Close();
    				stmGrades->Close();
    			}
    		}
    		else
    		{	
    			stmGrades = new FileStream(this->saveFileDialog1->FileName, FileMode::Create);
    			bnwGrades = new BinaryWriter(stmGrades);
    						
    			bnwGrades->Write(this->txtStudentName->Text);
    			bnwGrades->Write(this->txtSchoolYear1->Text);
    			bnwGrades->Write(this->txtSchoolYear2->Text);
    			bnwGrades->Write(this->txtEnglish->Text->ToDouble(0));
    			bnwGrades->Write(this->txtHistory->Text->ToDouble(0));
    			bnwGrades->Write(this->txtEconomics->Text->ToDouble(0));
    			bnwGrades->Write(this->txt2ndLanguage->Text->ToDouble(0));
    			bnwGrades->Write(this->txtGeography->Text->ToDouble(0));
    			bnwGrades->Write(this->txtArts->Text->ToDouble(0));
    			bnwGrades->Write(this->txtMath->Text->ToDouble(0));
    			bnwGrades->Write(this->txtScience->Text->ToDouble(0));
    			bnwGrades->Write(this->txtPhysEduc->Text->ToDouble(0));
    					
    			bnwGrades->Close();
    			stmGrades->Close();
    		}
    	}
    }
  6. Execute the application and create a record:
     
    Red Oak High School
  7. Save the record and close the form

 

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:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";
/*
	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
	BinaryWriter *wrtPersons = new BinaryWriter(fstPersons);

	wrtPersons->Write(S"James Bloch");
	wrtPersons->Write(S"Catherina Wallace");
	wrtPersons->Write(S"Bruce Lamont");
	wrtPersons->Write(S"Douglas Truth");

	wrtPersons->Close();
	fstPersons->Close();
*/
	FileStream *fstPersons = new FileStream(fileName, 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 support this, the class provides an appropriate method 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() method.

Here is an example of using the mentioned methods:

void StartProcessing(Object *o, EventArgs *e)
{
	String *fileName = S"Persons.spr";
/*
	FileStream *fstPersons = new FileStream(fileName, FileMode::Create);
	BinaryWriter *wrtPersons = new BinaryWriter(fstPersons);

	wrtPersons->Write(S"James Bloch");
	wrtPersons->Write(S"Catherina Wallace");
	wrtPersons->Write(S"Bruce Lamont");
	wrtPersons->Write(S"Douglas Truth");

	wrtPersons->Close();
	fstPersons->Close();
*/
	FileStream   *fstPersons = new FileStream(fileName, FileMode::Open);
	BinaryReader *rdrPersons = new BinaryReader(fstPersons);

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

Practical LearningPractical Learning: Reading From a Stream

  1. In the Toolbox, click the OpenFileDialog button SaveFileDialog and click the form
  2. In the Properties window, change the following properties
    DefaultExt: ros
    Filter: ROSH Students Grades (*.ros)|*.ros|All Files(*.*)|
    Title: Open Student Grades
  3. On the form, double-click the Save button and implement its Click event as follows:
     
    System::Void btnOpen_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 // Display the Open dialog box
    	 // Find out if the user selected a file and clicked OK
    	 if( this->openFileDialog1->ShowDialog() == DialogResult::OK )
    	 {
    	 FileStream   *stmGrades = new FileStream(this->openFileDialog1->FileName, FileMode::Open);
    		 BinaryReader *bnrGrades = new BinaryReader(stmGrades);
    
    		 if( File::Exists(this->openFileDialog1->FileName) )
    		 {
    			 // Retrieve the values from the file
    			 this->txtStudentName->Text = bnrGrades->ReadString();
    			 this->txtSchoolYear1->Text = bnrGrades->ReadString();
    			 this->txtSchoolYear2->Text = bnrGrades->ReadString();
    			 this->txtEnglish->Text     = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtHistory->Text     = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtEconomics->Text   = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txt2ndLanguage->Text = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtGeography->Text   = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtArts->Text        = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtMath->Text        = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtScience->Text     = bnrGrades->ReadDouble().ToString(S"F");
    			 this->txtPhysEduc->Text    = bnrGrades->ReadDouble().ToString(S"F");
    			 
    			 // Close the stream
    			 bnrGrades->Close();
    			 stmGrades->Close();
    
    			 // Since we didn't save the results of the calculations,
    			 // call the Calculate button to do it
    			 this->btnCalculate_Click(sender, e);
    		 }
    	 }
    }
  4. Execute the application and open the previously saved record
 

Previous Copyright © 2004-2012, FunctionX Next