17.5 Case Study: Credit-Inquiry Program

To retrieve data sequentially from a file, programs normally start from the beginning of the file, reading consecutively until the desired data is found. It sometimes is necessary to process a file sequentially several times (from the beginning of the file) during the execution of a program. A FileStream object can reposition its file-position pointer (which contains the byte number of the next byte to be read from or written to the file) to any position in the file. When a FileStream object is opened, its file-position pointer is set to byte position 0 (i.e., the beginning of the file).

We now present a program that builds on the concepts employed in Fig. 17.6. Class CreditInquiryForm (Fig. 17.7) is a credit-inquiry program that enables a credit manager to search for and display account information for those customers with credit balances (i.e., customers to whom the company owes money), zero balances (i.e., customers who do not owe the company money) and debit balances (i.e., customers who owe the company money for previously received goods and services). We use a RichTextBox in the program to display the account information. RichTextBoxes provide more functionality than regular TextBoxes—for example, RichTextBoxes offer method Find for searching individual strings and method LoadFile for displaying file contents. Classes RichTextBox and TextBox both inherit from abstract class System.Windows.Forms.TextBoxBase. In this example, we chose a RichTextBox, because it displays multiple lines of text by default, whereas a regular TextBox displays only one. Alternatively, we could have specified that a TextBox object display multiple lines of text by setting its Multiline property to true.

The program displays buttons that enable a credit manager to obtain credit information. The Open File button opens a file for gathering data. The Credit Balances button displays a list of accounts that have credit balances, the Debit Balances button displays a list of accounts that have debit balances and the Zero Balances button displays a list of accounts that have zero balances. The Done button exits the app.

Fig. 17.7 Credit-inquiry program.

Alternate View

  1    // Fig. 17.7: CreditInquiryForm.cs
  2    // Read a file sequentially and display contents based on
  3    // account type specified by user (credit, debit or zero balances).
  4    using System;
  5    using System.Windows.Forms;
  6    using System.IO;
  7    using BankLibrary;
  8
  9    namespace CreditInquiry
 10    {
 11       public partial class CreditInquiryForm : Form
 12       {
 13          private FileStream input; // maintains the connection to the file
 14          private StreamReader fileReader; // reads data from text file    
 15
 16          // parameterless constructor
 17          public CreditInquiryForm()
 18          {
 19             InitializeComponent();
 20          }
 21         
 22          // invoked when user clicks Open File button
 23          private void openButton_Click(object sender, EventArgs e)
 24          {
 25             // create dialog box enabling user to open file
 26             DialogResult result;
 27             string fileName;
 28         
 29             using (OpenFileDialog fileChooser = new OpenFileDialog())
 30              {
 31                 result = fileChooser.ShowDialog();
 32                 fileName = fileChooser.FileName;
 33              }
 34         
 35              // exit event handler if user clicked Cancel
 36              if (result == DialogResult.OK)
 37              {
 38                 // show error if user specified invalid file
 39                 if (string.IsNullOrEmpty(fileName))
 40                 {
 41                    MessageBox.Show("Invalid File Name", "Error",
 42                       MessageBoxButtons.OK, MessageBoxIcon.Error);
 43                 }
 44                 else
 45                 {
 46                    // create FileStream to obtain read access to file
 47                    input = new FileStream(fileName,   
 48                       FileMode.Open, FileAccess.Read);
 49         
 50                    // set file from where data is read
 51                    fileReader = new StreamReader(input);
 52
 53                    // enable all GUI buttons, except for Open File button
 54                    openButton.Enabled = false;
 55                    creditButton.Enabled = true;
 56                    debitButton.Enabled = true;
 57                    zeroButton.Enabled = true;
 58                  }
 59              }
 60          }
 61         
 62          // invoked when user clicks credit balances,
 63          // debit balances or zero balances button
 64          private void getBalances_Click(object sender, System.EventArgs e)
 65          {
 66             // convert sender explicitly to object of type button
 67             Button senderButton = (Button) sender;
 68         
 69             // get text from clicked Button, which stores account type
 70             string accountType = senderButton.Text;
 71         
 72             // read and display file information
 73             try
 74             {
 75                 // go back to the beginning of the file
 76                 input.Seek(0, SeekOrigin.Begin);
 77         
 78                 displayTextBox.Text =
 79                    $"Accounts with {accountType}{Environment.NewLine}";
 80                
 81                 // traverse file until end of file
 82                 while (true)
 83                 {
 84                    // get next Record available in file
 85                    string inputRecord = fileReader.ReadLine();
 86                
 87                     // when at the end of file, exit method
 88                     if (inputRecord == null)
 89                     {
 90                        return;
 91                     }
 92                
 93                     // parse input
 94                     string[] inputFields = inputRecord.Split(',');
 95                
 96                     // create Record from input
 97                     var record =
 98                        new Record(int.Parse(inputFields[0]), inputFields[1],
 99                           inputFields[2], decimal.Parse(inputFields[3]));
100                
101                    // determine whether to display balance
102                    if (ShouldDisplay(record.Balance, accountType))
103                    {
104                       // display record
105                       displayTextBox.AppendText($"{record.Account}	" +
106                          $"{record.FirstName}	{record.LastName}	" +
107                          $"{record.Balance:C}{Environment.NewLine}");
108                    }
109                 }
110             }
111             catch (IOException)
112             {
113                MessageBox.Show("Cannot Read File", "Error",
114                   MessageBoxButtons.OK, MessageBoxIcon.Error);
115             }
116          }
117
118          // determine whether to display given record
119          private bool ShouldDisplay(decimal balance, string accountType)
120          {
121             if (balance > 0M && accountType == "Credit Balances")
122             {
123                return true; // should display credit balances
124             }
125             else if (balance < 0M && accountType == "Debit Balances")
126             {
127                return true; // should display debit balances
128             }
129             else if (balance == 0 && accountType == "Zero Balances")
130             {
131                return true; // should display zero balances
132             }
133         
134              return false;
135          }
136         
137          // invoked when user clicks Done button
138          private void doneButton_Click(object sender, EventArgs e)
139          {
140             // close file and StreamReader
141             try
142             {
143                fileReader?.Close(); // close StreamReader and underlying file
144             }
145             catch (IOException)
146             {
147                 // notify user of error closing file
148                 MessageBox.Show("Cannot close file", "Error",
149                    MessageBoxButtons.OK, MessageBoxIcon.Error);
150             }
151         
152              Application.Exit();
153           }
154       }
155    }

When the user clicks the Open File button, the program calls the event handler openButton_Click (lines 23–60). Line 29 creates an OpenFileDialog, and line 31 calls its ShowDialog method to display the Open dialog, in which the user selects the file to open. Lines 47–48 create a FileStream object with read-only file access and assign it to reference input. Line 51 creates a StreamReader object that we use to read text from the FileStream.

When the user clicks Credit Balances, Debit Balances or Zero Balances, the program invokes method getBalances_Click (lines 64–116). Line 67 casts the sender parameter, which is an object reference to the control that generated the event, to a Button object. Line 70 extracts the Button object’s text, which the program uses to determine which type of accounts to display. Line 76 uses FileStream method Seek to reset the file-position pointer back to the beginning of the file. FileStream method Seek allows you to reset the file-position pointer by specifying the number of bytes it should be offset from the file’s beginning, end or current position. The part of the file you want to be offset from is chosen using constants from the SeekOrigin enumeration. In this case, our stream is offset by 0 bytes from the file’s beginning (SeekOrigin.Begin). Line 102 use private method ShouldDisplay (lines 119–135) to determine whether to display each record in the file. The while loop obtains each record by repeatedly calling StreamReader method ReadLine (line 85) and splitting the text into tokens (line 94) that are used to initialize object record (lines 97–99). Line 88 determines whether the file-position pointer has reached the end of the file, in which case ReadLine returns null. If so, the program returns from method getBalances_Click (line 90).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset