Chapter 10 Sequential Files and Structures
Class 10: Sequential Files Work with different types of sequential files Read sequential files based on the type of data stored in a text file Write sequential files Use structures to store and group data together
The OpenFileDialog and SaveFileDialog Controls All dialog boxes derive from the CommonDialog class and share similar features –The OpenFileDialog and SaveFileDialog controls are derived from the CommonDialog class These classes allow the end user to select a file to open or save –The FolderBrowserDialog control also derives from the CommonDialog class This control allows the end user to select a folder
Figure 10-1: Hierarchical Relationships Among Dialog Classes
Members of the OpenFileDialog and SaveFileDialog Classes The CheckFileExists and CheckPathExists properties control whether the end user can select a file or folder that does not exist The FileName property contains the filename selected by the end user The Filter property defines the type of files that will be displayed for selection The FilterIndex property contains the index of the current filter –The Filter and FilterIndex properties work together
Members of the OpenFileDialog and SaveFileDialog Classes (continued) The InitialDirectory property contains the initial folder where the search for files begins The OverwritePrompt property applies only to the SaveFileDialog ; if True, the end user will be prompted before a file is overwritten The RestoreDirectory property defines whether the current directory will be restored after the end user selects a file The ShowDialog method displays the respective dialog box
Figure 10-2: Visual Elements of the Open Dialog Box
The Filter Property (Introduction) The Filter property restricts the files displayed based on a file extension A filter consists of –A description –Followed by a vertical bar –Followed by the actual filter Multiple filters can be connected together Do not put spaces between the vertical bars
The Filter Property (Syntax) Object.Filter = [description1|filter1|description2 |filter2...] –description1 contains the description of the filter –filter1 contains the filter itself The characters '*.' precede the three-character file extension of the filter Use '*.*' to select all files –Vertical bars separate each description, filter pair
The Filter Property (Example) Set the Filter to three possible filters (*.txt), (*.rtf), and (*.*) Set the FilterIndex to select the second filter by default ofdMain.Filter = "Text files (*.txt)|*.txt|" _ "Rich text files (*.rtf)|*.rtf|All files" _ "(*.*)|*.*" ofdMain.FilterIndex = 2
Using the SaveFileDialog Control The SaveFileDialog control works the same way as the OpenFileDialog control Set the OverwritePrompt property to True to prevent the end user from accidentally overwriting files
Figure 10-3: Overwrite Prompt Message
Displaying the SaveFileDialog (Example) Display an instance of the SaveFileDialog control named sfdMain If the user clicks OK, store the filename in the text box named txtFileName Dim Result As DialogResult sfdMain.OverwritePrompt = True Result = sfdMain.ShowDialog() If Result = Windows.Forms.DialogResult.OK Then txtFileName.Text = sfdMain.FileName End If
The FolderBrowserDialog (Introduction) Use the FolderBrowserDialog to browse for folders instead of files Members –The Description property contains the text appearing in the title bar –The RootFolder property contains the topmost folder appearing in the dialog box –The SelectedPath property contains the folder selected by the end user –The ShowDialog method displays the dialog box
Figure 10-4: The FolderBroswerDialog Control
Using Windows Defined Directories Members of the System.Environment class are used to get system directories –The SystemDirectory property gets the Windows system directory The directory is typically C:\Windows\System –The CurrentDirectory property contains the directory from which the application was run –The GetFolderPath method gets a system special folder
Table 10-1: Special Folders
Reading a Special Folder (Example) Get the special folder corresponding to the Desktop Dim DirectoryString As String DirectoryString = Environment.GetFolderPath( _ Environment.SpecialFolder.Desktop)
Using Application-defined Directories The Application class contains application defined directories –The StartupPath property contains the directory from which the application was started –The ExecutablePath property contains the startup path and executable filename –The UserAppDataPath and LocalUserAppDataPath properties return application data directories
Introduction to Processing Textual Data One way to process textual files is from beginning to end using sequential access This type of file is called a sequential file Sequential files can be categorized into roughly three types –Free-form files have no particular format –Fields in a delimited file are separated with a special character called a delimiter –In a fixed-field file, each field occupies the same character positions
The Format of Freeform Files Freeform files have no particular format The file contains one or more textual characters appearing on one or many lines The number of lines in the file is not significant Freeform files can be read character-by- character or all at once
The Format of Delimited Files All delimited files have a well-defined structure and the following characteristics: –Sequential files are separated into lines ending with a hard return –Each line in a sequential file is called a record –Each record contains one or more fields –A delimiter, often a comma, separates fields A delimiter can consist of multiple characters
Figure 10-6: Delimited Sequential File
The Format of Fixed-field Files Fixed-field files contain textual characters A specific character position marks the start and end of each field Each record is terminated with a hard return
Figure 10-7: Fixed-field File
Opening and Closing Sequential Files with the StreamReader The StreamReader and StreamWriter classes belong to the System.IO namespace Opening a sequential file establishes a connection between an application and a physical file Sequential files can be read one character at a time, one line at a time, or the entire file can be read at once Sequential files are typically read into a string or an array Closing a file disconnects the application from the file
The StreamReader Constructor (Syntax) Public Sub New(ByVal path As String) –The StreamReader constructor accepts one argument – the path and filename of the sequential file to open
The StreamReader Constructor (Example) Open a file named "C:\Demo.txt" Dim CurrentReader As _ System.IO.StreamReader = _ New System.IO.StreamReader( _ "C:\Demo.txt")
Closing a Sequential File The Close method closes a sequential file Always close files when processing is complete to prevent loss of data Open files also consume system resources Example: CurrentReader.Close()
The StreamReader Class (Members) The Close method closes an open file The Peek method gets the next character without actually reading the character –The method returns the Integer code point of the character that will be read –The method returns -1 if there are no more characters to read The Read method reads a single character or many characters –Without arguments, the Read method returns the Integer code point of the character read
The StreamReader Class (Members, continued) The ReadLine method reads a record –The carriage return at the end of the record is discarded –The method returns a String containing the characters read The ReadToEnd method reads from the current file position to the end of the file –The method returns a String containing the characters read
Reading the Entire Contents of a File (Example) Read the file named "C:\Demo.txt" Dim CurrentString As String Dim CurrentReader As New _ StreamReader("C:\Demo.txt") CurrentString = _ CurrentReader.ReadToEnd() CurrentReader.Close()
Reading a Sequential File Character by Character It's possible to read a sequential file character-by-character Steps: –Call the Read method to perform a priming read –In a loop, test that a character was read (Check that end-of-file was not reached) Process the character Read the next character
Figure 10-8: Flowchart to Read a Sequential File Character by Character
Reading a Sequential File Character by Character (Example) Dim CurrentChar As Integer Dim CurrentReader As New _ StreamReader("C:\Demo.txt") CurrentChar = CurrentReader.Read() Do Until CurrentChar = –1 ' Statements to process the character. CurrentChar = CurrentReader.Read() Loop CurrentReader.Close()
Reading a Sequential File One Record at a Time Delimited files are processed using the following steps: –Call the ReadLine method to perform a priming read –Using a Do loop, process the record that was read –Read the next record –After reading all records, close the file
Figure 10-9: Reading a Sequential File as a List of Records
Reading a Sequential File as a List of Records (Example) Dim CurrentReader As New _ System.IO.StreamReader("C:\Demo.txt") Dim CurrentRecord As String CurrentRecord = CurrentReader.ReadLine() Do Until CurrentRecord = Nothing ' Statements to process the current record. CurrentRecord = CurrentReader.ReadLine() Loop CurrentReader.Close()
Understanding the Split Method The Split method of the String class parses a string into an array of strings –The string is parsed based on the character or characters designated as the delimiter The Split method accepts an argument containing the delimiter This argument is an array of type Char
Storing Data in a Char Data Type Call the ToChar method of the System.Convert class as follows: –Even though the comma is a single character, it is considered a string and must be explicitly converted to a Char Dim DelimiterChar As Char DelimiterChar = _ System.Convert.ToChar(",")
Storing an Array of Type Char The Split method requires an array of type Char to store the delimiter Example 1: Dim DelimiterChar As Char = ToChar(",") Dim DelimiterChars() As Char = {DelimiterChar} Example 2: Dim DelimiterChars() As Char = {ToChar(",")}
The Split Method (Example) Split a string using a comma as a delimiter Dim CurrentRecord As String = _ "Field1, Field2, Field3" Dim Fields() As String Dim Delimiter() As Char = {ToChar(",")} Fields = CurrentRecord.Split(Delimiter)
Figure 10-10: Splitting a Text Line
Common Sequential File Errors In the loop that processes the current record and reads the next record, it is common to forget to read the next record, causing an infinite loop It's common to forget to perform the priming read on a file –In such a case, no records will be read The current record must be processed before reading the next record
Writing a Sequential File The StreamWriter class of the System.IO namespace writes a sequential file The constructor accepts one argument – the file to write Example: Dim CurrentWriter As New _ System.IO.StreamWriter("C:\Demo.txt") ' Statements to write the file. CurrentWriter.Close()
The StreamWriter Class (Members) The NewLine property contains the character(s) that mark the end of the line The Close method closes the sequential file –It's imperative to close a sequential file once writing is complete to prevent loss of data The Write method writes a character or array of characters The WriteLine method writes data terminated by the character(s) stored in the NewLine property
Writing a Freeform File A freeform file can be written all at once as follows: Dim StringData As String = "Freeform text" Dim CurrentWriter As New _ System.IO.StreamWriter("C:\Demo.txt") CurrentWriter.Write(StringData) CurrentWriter.Close()
Writing a Delimited File The steps to write delimited file are as follows: –Create an instance of the StreamWriter class –Using a For loop, call the WriteLine method to write each record –Call the Close method when writing is complete
Writing a Delimited File (Example) Write an array of Integers Public Shared Sub WriteIntegerList( _ ByRef argArray() As Integer, _ ByVal argFile As String) Dim CurrentStream As New StreamWriter(argFile) Dim CurrentIndex As Integer For CurrentIndex = 0 To argArray.GetUpperBound(0) CurrentStream.Write(argArray(CurrentIndex)) If CurrentIndex <> _ argArray.GetUpperBound(0) Then CurrentStream.Write(",") End If Next CurrentStream.Close() End Function
Introduction to Structures A structure is used to store related data items, and groups them together logically A structure can take the place of multiple individual variables The Structure keyword is used to declare a structure –Once declared, variables can be declared having the declared data type
Structures (Syntax) [Public | Friend] Structure name variableDeclarations [procedureDeclarations] End Structure
Structures (Syntax, continued) The Structure and End Structure keywords mark the beginning and end of a structure block The Public and Friend keywords mark the accessibility of the structure name defines the structure name –Use Pascal case for structure names variableDeclarations contains the structure members procedureDeclarations contains procedures appearing in the structure
Structures (Example) Declare a structure named Contact with four members Public Structure Contact Public FirstName As String Public LastName As String Public TelephoneNumber As String Public DateAdded As DateTime End Structure
Declaring Structures Structures can be declared in a Class or Module block A Structure block can contain a nested Structure block A Structure block cannot appear inside of a procedure block A structure can have members that are themselves structures
Declaring a Structure Variable Declaring a Structure block does not declare a variable –It declares a new type The syntax to declare a structure is the same as the syntax to declare any other variable Examples: Dim CurrentContact As Contact Dim PreviousContact As Contact
Declaring a Structure Variable (continued) It's also possible to declare an array of structures Examples: Public ContactList() As Contact ReDim ContactList(9) As Contact
Storing and Retrieving Data From a Structure Assignment statements are used to store and retrieve data from a structure A period (.) separates the structure variable name and the member name Examples: CurrentContact.FirstName = "Joe" CurrentContact.LastName = "Smith" CurrentContact.Telephone = " " CurrentContact.DateAdded = #3/22/2006#
Assignment Statements Using Structures Structures can be used on both the left and right side of assignment statements –As always, the data types of each side of the expression must match Examples: PreviousContact.FirstName = _ CurrentContact.FirstName PreviousContact.LastName = _ CurrentContact.LastName PreviousContact.Address = _ CurrentContact.Address PreviousContact.DateAdded = _ CurrentContact.DateAdded
The With Statement (Introduction) The With statement supplies a shorthand way of referencing structure and class members A With block begins with the With statement and ends with the End With statement
The With Statement (Example) With CurrentContact.FirstName = "Joe".LastName = "Smith".Telephone = " ".DateAdded = #3/22/2006# End With
Restrictions on the With Statement Decision-making statements cannot break up a With block Repetition structures cannot break up a With block
Using Arrays of Structures It's possible to declare arrays of structures Following the structure variable name, the array subscript appears Following the array subscript, the structure member appears
Using Arrays of Structures (Example) Store data in the first element of the array named ContactList Private ContactList(99) As Contact ContactList(0).FirstName = "Joe" ContactList(0).LastName = "Smith" ContactList(0).Telephone = " " ContactList(0).DateAdded = #3/22/2006#
Processing Delimited Files Using Arrays of Structures A sequential file can be read into an array of structures Steps: –Read the first record performing the priming read –In a loop: Parse and process the current record Read the next record until there are no more records