Reading and Deserializing Data from a Sequential-Access Text File
The preceding section showed how to create a sequential-access file using object serialization. In this section, we discuss how to read serialized objects sequentially from a file.
Figure 18.15 reads and displays the contents of the file created by the program in Fig. 18.14. Line 13 creates the BinaryFormatter that will be used to read objects. The program opens the file for input by creating a FileStream object (lines 4445). The name of the file to open is specified as the first argument to the FileStream constructor.
Figure 18.15. Sequential file read using deserialzation.
1 // Fig. 18.15: ReadSequentialAccessFileForm.cs
2 // Reading a sequential-access file using deserialization.
3 using System;
4 using System.Windows.Forms;
5 using System.IO;
6 using System.Runtime.Serialization.Formatters.Binary;
7 using System.Runtime.Serialization;
8 using BankLibrary;
9
10 public partial class ReadSequentialAccessFileForm : BankUIForm
11 {
12 // object for deserializing Record in binary format
13 private BinaryFormatter reader = new BinaryFormatter();
14 private FileStream input; // stream for reading from a file
15
16 // parameterless constructor
17 public ReadSequentialAccessFileForm()
18 {
19 InitializeComponent();
20 } // end constructor
21
22 // invoked when user clicks Open button
23 private void openButton_Click( object sender, EventArgs e )
24 {
25 // create dialog box enabling user to open file
26 OpenFileDialog fileChooser = new OpenFileDialog();
27 DialogResult result = fileChooser.ShowDialog();
28 string fileName; // name of file containing data
29
30 // exit event handler if user clicked Cancel
31 if ( result == DialogResult.Cancel )
32 return;
33
34 fileName = fileChooser.FileName; // get specified file name
35 ClearTextBoxes();
36
37 // show error if user specified invalid file
38 if ( fileName == "" || fileName == null )
39 MessageBox.Show( "Invalid File Name", "Error",
40 MessageBoxButtons.OK, MessageBoxIcon.Error );
41 else
42 {
43 // create FileStream to obtain read access to file
44 input = new FileStream(
45 fileName, FileMode.Open, FileAccess.Read );
46
47 openButton.Enabled = false; // disable Open File button
48 nextButton.Enabled = true; // enable Next Record button
49 } // end else
50 } // end method openButton_Click
51
52 // invoked when user clicks Next button 53 private void nextButton_Click( object sender, EventArgs e ) 54 { 55 // deserialize Record and store data in TextBoxes 56 try 57 { 58 // get next RecordSerializable available in file 59 RecordSerializable record = 60 ( RecordSerializable ) reader.Deserialize( input ); 61 62 // store Record values in temporary string array 63 string[] values = new string[] { 64 record.Account.ToString(), 65 record.FirstName.ToString(), 66 record.LastName.ToString(), 67 record.Balance.ToString() 68 }; 69 // copy string array values to TextBox values 70 SetTextBoxValues( values ); 71 } // end try 72 // handle exception when there are no Records in file 73 catch( SerializationException ) 74 { 75 input.Close(); // close FileStream if no Records in file 76 openButton.Enabled = true; // enable Open File button 77 nextButton.Enabled = false; // disable Next Record button 78 79 ClearTextBoxes(); 80 81 // notify user if no Records in file 82 MessageBox.Show( "No more records in file", "", 83 MessageBoxButtons.OK, MessageBoxIcon.Information ); 84 } // end catch 85 } // end method nextButton_Click 86 } // end class readSequentialAccessFileForm
|
The program reads objects from a file in event handler nextButton_Click (lines 5385). We use method Deserialize (of the BinaryFormatter created in line 13) to read the data (lines 5960). Note that we cast the result of Deserialize to type RecordSerializable (line 60)this cast is necessary, because Deserialize returns a reference of type object and we need to access properties that belong to class RecordSerializable. If an error occurs during deserialization, a SerializationException is thrown, and the FileStream object is closed (line 75).