- Key Classes Related to File I/O
- Directory and File Operations
- Reading and Writing to Files and Streams
- Learning By Example: Adding Open and Save to FontPad
- Summary
Learning By Example: Adding Open and Save to FontPad
Recall FontPad from Chapter 6, "Font, Text, and Printing." This was our basic text editor to which we then added printing capabilities. We will round out this application by adding basic file I/O. After all, what's a text editor worth if it can't open and save files? By the time we're done, we should have completely replaced (or duplicated, anyway) the functionality of Notepad.
This example extends FontPad with an open and save dialog. Therefore, only the open and save dialogs are discussed here. To run the application, you should download the full source at http://www.samspublishing.com. After walking through the application, you should be able to extend the example as a test harness in which you can experiment with your own code.
Key Concepts Covered
The following represents the key class and concepts demonstrated with this sample application:
Accessing directory properties and enumerating directories with the DirectoryInfo class.
Accessing file properties and enumerating files in a directory with the FileInfo class.
Reading a file with the FileStream and StreamReader classes.
Persisting a file to disk with the FileStream and StreamWriter classes.
Open Dialog
To open files, we must present users with a method to browse the file system. .NET provides us with a FileDialog class specifically designed for this purpose. This class is similar to the common dialogs with which we're familiar from the VB of old. The .NET team built the dialog using the namespace we've presented in this chapter.
In our example application we will create our own dialog using the namespace rather than FileDialog. This makes sense because our objective is to teach the namespace. However, we suggest you further explore this class if you need fast and easy access to the file system. Figure 7.3 is a screen capture of our open dialog.
Obviously, this form will not win any usability or user interface design awards; it was built to illustrate code. There are two list boxes on the form. One maintains a current list of subdirectories of the given path. The other displays files of type text within the selected directory. Users navigate down through subdirectories by double-clicking a directory. To navigate back, they click the Up button. As directories and files are selected, we write related information to a couple of label controls.
Figure 7.3 FontPad: Open form screen shot.
Code Walkthrough
The code used by the open dialog should be very familiar to you by now. The code can be found in Listing 7.8.
The code starts with some form-level declarations for directory name and filename. This is followed by the basic code to build the form.
LISTING 7.8 FontPad: Open Form (formOpen.vb)
Public Class formOpen Inherits System.Windows.Forms.Form 'form-level scope declarations Dim myDirName As String Dim myFileName As String # Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'Form overrides dispose to clean up the component list. Public Overloads Overrides Sub Dispose() MyBase.Dispose() If Not (components Is Nothing) Then components.Dispose() End If End Sub Private WithEvents buttonOk As System.Windows.Forms.Button Private WithEvents buttonCancel As System.Windows.Forms.Button Private WithEvents listBox1 As System.Windows.Forms.ListBox Private WithEvents labelCurrentDir As System.Windows.Forms.Label Private WithEvents buttonUp As System.Windows.Forms.Button Private WithEvents labelDirInfo As System.Windows.Forms.Label Private WithEvents label2 As System.Windows.Forms.Label Private WithEvents label1 As System.Windows.Forms.Label Private WithEvents labelFileInfo As System.Windows.Forms.Label Private WithEvents listBoxFiles As System.Windows.Forms.ListBox Private WithEvents listBoxDirectories As System.Windows.Forms.ListBox Private WithEvents label5 As System.Windows.Forms.Label Private WithEvents label3 As System.Windows.Forms.Label 'Required by the Windows Form Designer Private components As System.ComponentModel.Container 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. < System.Diagnostics.DebuggerStepThrough()> Private Sub _ InitializeComponent() Me.labelDirInfo = New System.Windows.Forms.Label() Me.listBoxFiles = New System.Windows.Forms.ListBox() Me.labelCurrentDir = New System.Windows.Forms.Label() Me.buttonCancel = New System.Windows.Forms.Button() Me.buttonUp = New System.Windows.Forms.Button() Me.listBoxDirectories = New System.Windows.Forms.ListBox() Me.listBox1 = New System.Windows.Forms.ListBox() Me.label5 = New System.Windows.Forms.Label() Me.labelFileInfo = New System.Windows.Forms.Label() Me.buttonOk = New System.Windows.Forms.Button() Me.label1 = New System.Windows.Forms.Label() Me.label2 = New System.Windows.Forms.Label() Me.label3 = New System.Windows.Forms.Label() Me.labelDirInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D Me.labelDirInfo.Location = New System.Drawing.Point(224, 96) Me.labelDirInfo.Size = New System.Drawing.Size(204, 72) Me.labelDirInfo.TabIndex = 7 Me.listBoxFiles.Location = New System.Drawing.Point(8, 196) Me.listBoxFiles.Size = New System.Drawing.Size(212, 134) Me.listBoxFiles.TabIndex = 9 Me.labelCurrentDir.BorderStyle = _ System.Windows.Forms.BorderStyle.Fixed3D Me.labelCurrentDir.Location = New System.Drawing.Point(8, 28) Me.labelCurrentDir.Size = New System.Drawing.Size(420, 16) Me.labelCurrentDir.TabIndex = 6 Me.labelCurrentDir.Text = "Current: " Me.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel Me.buttonCancel.Location = New System.Drawing.Point(352, 336) Me.buttonCancel.TabIndex = 0 Me.buttonCancel.Text = "Cancel" Me.buttonUp.Location = New System.Drawing.Point(224, 48) Me.buttonUp.Size = New System.Drawing.Size(28, 24) Me.buttonUp.TabIndex = 5 Me.buttonUp.Text = "up" Me.listBoxDirectories.Location = New System.Drawing.Point(8, 48) Me.listBoxDirectories.Size = New System.Drawing.Size(212, 121) Me.listBoxDirectories.TabIndex = 4 Me.listBox1.Location = New System.Drawing.Point(20, 60) Me.listBox1.Size = New System.Drawing.Size(0, 4) Me.listBox1.TabIndex = 3 Me.label5.Location = New System.Drawing.Point(224, 180) Me.label5.Size = New System.Drawing.Size(92, 16) Me.label5.TabIndex = 2 Me.label5.Text = "Info" Me.labelFileInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D Me.labelFileInfo.Location = New System.Drawing.Point(224, 196) Me.labelFileInfo.Size = New System.Drawing.Size(204, 132) Me.labelFileInfo.TabIndex = 7 Me.buttonOk.Location = New System.Drawing.Point(272, 336) Me.buttonOk.TabIndex = 1 Me.buttonOk.Text = "OK" Me.label1.Location = New System.Drawing.Point(8, 8) Me.label1.Size = New System.Drawing.Size(100, 16) Me.label1.TabIndex = 8 Me.label1.Text = "Directories" Me.label2.Location = New System.Drawing.Point(224, 80) Me.label2.Size = New System.Drawing.Size(92, 16) Me.label2.TabIndex = 2 Me.label2.Text = "Info" Me.label3.Location = New System.Drawing.Point(6, 180) Me.label3.Size = New System.Drawing.Size(100, 16) Me.label3.TabIndex = 8 Me.label3.Text = "Files" Me.AcceptButton = Me.buttonOk Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog Me.CancelButton = Me.buttonCancel Me.ClientSize = New System.Drawing.Size(433, 366) Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.label5, _ Me.labelFileInfo, Me.label3, Me.listBoxFiles, Me.label1, _ Me.labelCurrentDir, Me.buttonUp, Me.listBoxDirectories, _ Me.labelDirInfo, Me.label2, Me.listBox1, Me.buttonOk, _ Me.buttonCancel}) Me.Text = "Open Text File" End Sub
On the form load event we simply make a call to the sub procedure that loads the directory list box.
Private Sub formOpen_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'purpose: load the form, init the controls 'local scope 'load the directory list box Call loadDirListBox() End Sub
The procedure loadDirListBox refreshes the contents of the directory list box when the form loads and as users double-click a subdirectory or press the Up button.
Private Sub loadDirListBox() 'purpose: load the list box control based on the current path 'local scope Dim myDirectory As System.IO.DirectoryInfo Dim myDirectories() As System.IO.DirectoryInfo Dim i As Integer 'clear the directory list box listBoxDirectories().Items().Clear() 'create a new directory object myDirectory = New System.IO.DirectoryInfo(path:=myPath) 'return the sub directories from the global directory object myDirectories = myDirectory.GetDirectories() 'loop through the directories and add them to the list box For i = 0 To UBound(myDirectories) - 1 'add the directory name to the list listBoxDirectories().Items.Add(myDirectories(i).Name) Next 'set the current label to indicate the current path labelCurrentDir().Text = "Current: " & myPath 'select the first directory in the list ' note: this will trigger the events that fill the label control ' and the files list box and its label control If listBoxDirectories().Items.Count > 0 Then listBoxDirectories().SelectedIndex = 0 End If End Sub
Once the user has selected a file to open and has clicked the OK button, the button's click event calls a custom procedure we call readFile.
Private Sub buttonOk_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonOk.Click 'purpose: respond to the OK button event ' validate the form ' open the user's selected file 'determine if the user does indeed have a text file selected If Not (listBoxFiles().SelectedIndex > -1) Then 'tell the user to select a text file to continue MsgBox(prompt:="Please select a text file.", _ buttons:=MsgBoxStyle.Information, title:="FontPad Open") Else 'open the text file as a stream and read it into our editor 'note: this new file will replace the current file without saving Call readFile() 'close the form Me.Close() End If End Sub
The readFile procedure creates a StreamReader object, sets its read position to the start of the file, and reads the file line-by-line. Finally, our rich text box control is updated with the contents of the opened file.
Private Sub readFile() 'purpose: read a file as a stream object ' and put its content in the rich text box 'local scope Dim fileStream As IO.FileStream Dim streamReader As IO.StreamReader 'handle any errors the occur when loading the file stream Try 'create a new instance of the file stream object ' based on the current path and selected file fileStream = New IO.FileStream(path:=myPath & myDirName & _ myFileName, mode:=IO.FileMode.Open, access:=IO.FileAccess.Read) 'create a stream reader instance streamReader = New IO.StreamReader(stream:=fileStream) 'set the file pointer to the start of the file streamReader.BaseStream.Seek(offset:=0, _ origin:=IO.SeekOrigin.Begin) 'set the textContents to nothing 'note the rich text box will be updated on form close textContents = "" 'loop through the file and write to internal string variable ' until end of file reached Do While streamReader.Peek > -1 textContents = textContents & streamReader.ReadLine() & vbCrLf Loop 'close the stream reader streamReader.Close() Catch 'indicate to the user that the file cannot be opened MsgBox(prompt:="Sorry, unable to open the selected file", _ buttons:=MsgBoxStyle.Exclamation, title:="FontPad Open") End Try End Sub
Inside the listBoxDirectories double-click event we simply reset the path (myPath) and call load directories sub (loadDirListBox).
Private Sub listBoxDirectories_DoubleClick(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles listBoxDirectories.DoubleClick 'purpose: manange the double-click event ' which allows users to navigate down directories 'local scope 'set the new global path myPath = myPath & myDirName 'update the list directory list box Call loadDirListBox() End Sub
When users select a directory from the list box, the directory list box's index change event gets fired. This event loads the file's list box based on the user-selected subdirectory. Inside this event, we trap for file security access issues. For instance, if you call the GetFiles method of the Directory object and the user is not granted access to the directory's files, we must raise this issue to our user.
Private Sub listBoxDirectories_SelectedIndexChanged( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles listBoxDirectories.SelectedIndexChanged 'purpose: update the directory info label and the file's list box ' when users select a directory 'local scope Dim myDirectory As System.IO.DirectoryInfo Dim dirInfo As String Dim myFiles() As System.IO.FileInfo Dim i As Integer 'clear the listbox of its current contents listBoxFiles().Items.Clear() 'clear the list box label labelFileInfo().Text = "" 'get a directory info object based on the user's selection myDirName = listBoxDirectories().SelectedItem.ToString & "\" myDirectory = New System.IO.DirectoryInfo( _ path:=(myPath & myDirName)) 'set the dir info dirInfo = dirInfo & "Attributes: " & myDirectory.Attributes.ToString labelDirInfo().Text = dirInfo 'get the files in the directory that are of type text 'NOTE: we handle security access exceptions Try myFiles = myDirectory.GetFiles(searchPattern:="*.txt") 'check for files If UBound(myFiles) >= 0 Then 'loop through the files array and add to the listbox For i = 0 To UBound(myFiles) - 1 listBoxFiles().Items.Add(myFiles(i).Name) Next 'select the file in the list, this will trigger the event to change ' the file info label control If listBoxFiles().Items.Count > 0 Then listBoxFiles().SelectedIndex = 0 End If End If Catch MsgBox(prompt:= _ "Sorry, but you do not have access to browse this folder's _ files.", buttons:=MsgBoxStyle.Exclamation, title:="FontPad Exception") End Try End Sub
When a user selects a file, the SelectedIndexChanged event is fired. This event allows us to set the selected filename (myFileName) and update the file properties to the user.
Private Sub listBoxFiles_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles listBoxFiles.SelectedIndexChanged 'purpose: change the contents of the file properties label 'local scope Dim myFile As System.IO.FileInfo Dim fileInfo As String 'set the file name myFileName = listBoxFiles().SelectedItem.ToString 'create a new file object myFile = New System.IO.FileInfo(fileName:=myPath & myDirName & _ myFileName) 'set the file info to display fileInfo = fileInfo & "Directory: " & _ myFile.DirectoryName & vbCrLf & vbCrLf fileInfo = fileInfo & "Created Time: " & _ CStr(myFile.CreationTime) & vbCrLf & vbCrLf fileInfo = fileInfo & "Size: " & _ CStr(myFile.Length / 100) & " KB" & vbCrLf & vbCrLf fileInfo = fileInfo & "Last Accessed: " & _ CStr(myFile.LastAccessTime) & vbCrLf & vbCrLf fileInfo = fileInfo & "Attributes: " & myFile.Attributes.ToString 'set the label to the file's info labelFileInfo().Text = fileInfo End Sub
The Up button's click event simply navigates the user back up one folder.
Private Sub buttonUp_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonUp.Click 'purpose: move back one directory 'local scope Dim intPos As Integer 'find the \ at the end of the path intPos = InStrRev(stringCheck:=Mid(myPath, 1, Len(myPath) - 1), _ stringMatch:="\") If intPos = 0 Then 'no more path info Beep() Else 'trim the path back myPath = Mid(myPath, 1, intPos) Call loadDirListBox() End If End Sub #End Region End Class
Save Dialog
Our application needs a way to persist its data to the file system. We create a Save dialog and associated code to do just that. Figure 7.4 is a screen capture of the Save dialog in action. Again, this dialog is sure to offend UI designers but it serves to illustrate the use of the classes.
The directory list box and associated Up button were stolen from the Open form. This simple paradigm provides users with access to the file system. A text box is provided for users to type the name to which they want to save the file.
Figure 7.4 FontPad: Save form.
The directory browsing provided by the form's code is nearly the same as the Open example (we might have considered creating a common dialog to be used by both features).
Code Walkthrough
Listing 7.9 presents the code behind the Open form.
Listing 7.9 starts with a form-level declare for storing the directory name. This is followed by the basic form code. After that, much of the code is similar to the code in the open dialog with the exception of the saveFile function.
LISTING 7.9 FontPad: Save Form (formSave.vb)
Public Class formSave Inherits System.Windows.Forms.Form 'form-level scope declarations Dim myDirName As String 'note: issues '1. cannot save to the root directory '2. the return character not coming out right '3. files saved cannot be seen by the open '4. delete the file if exists?? #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'Form overrides dispose to clean up the component list. Public Overloads Overrides Sub Dispose() MyBase.Dispose() If Not (components Is Nothing) Then components.Dispose() End If End Sub Private WithEvents label1 As System.Windows.Forms.Label Private WithEvents buttonOk As System.Windows.Forms.Button Private WithEvents buttonCancel As System.Windows.Forms.Button Private WithEvents buttonUp As System.Windows.Forms.Button Private WithEvents label2 As System.Windows.Forms.Label Private WithEvents textBoxFileName As System.Windows.Forms.TextBox Private WithEvents listBoxDirectories As System.Windows.Forms.ListBox Private WithEvents labelSaveTo As System.Windows.Forms.Label 'Required by the Windows Form Designer Private components As System.ComponentModel.Container 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub _ InitializeComponent() Me.label1 = New System.Windows.Forms.Label() Me.buttonOk = New System.Windows.Forms.Button() Me.label2 = New System.Windows.Forms.Label() Me.buttonCancel = New System.Windows.Forms.Button() Me.listBoxDirectories = New System.Windows.Forms.ListBox() Me.labelSaveTo = New System.Windows.Forms.Label() Me.textBoxFileName = New System.Windows.Forms.TextBox() Me.buttonUp = New System.Windows.Forms.Button() Me.SuspendLayout() ' 'label1 ' Me.label1.Location = New System.Drawing.Point(8, 8) Me.label1.Name = "label1"1 Me.label1.Size = New System.Drawing.Size(124, 23) Me.label1.TabIndex = 2 Me.label1.Text = "Save to directory:" ' 'buttonOk ' Me.buttonOk.Location = New System.Drawing.Point(136, 220) Me.buttonOk.Name = "buttonOk" Me.buttonOk.TabIndex = 1 Me.buttonOk.Text = "OK" ' 'label2 ' Me.label2.Location = New System.Drawing.Point(4, 172) Me.label2.Name = "label2" Me.label2.TabIndex = 2 Me.label2.Text = "File name:" ' 'buttonCancel ' Me.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel Me.buttonCancel.Location = New System.Drawing.Point(216, 220) Me.buttonCancel.Name = "buttonCancel" Me.buttonCancel.TabIndex = 0 Me.buttonCancel.Text = "Cancel" ' 'listBoxDirectories ' Me.listBoxDirectories.Location = New System.Drawing.Point(8, 72) Me.listBoxDirectories.Name = "listBoxDirectories" Me.listBoxDirectories.Size = New System.Drawing.Size(244, 95) Me.listBoxDirectories.TabIndex = 3 ' 'labelSaveTo ' Me.labelSaveTo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D Me.labelSaveTo.Location = New System.Drawing.Point(8, 28) Me.labelSaveTo.Name = "labelSaveTo" Me.labelSaveTo.Size = New System.Drawing.Size(280, 36) Me.labelSaveTo.TabIndex = 6 ' 'textBoxFileName ' Me.textBoxFileName.Location = New System.Drawing.Point(8, 192) Me.textBoxFileName.Name = "textBoxFileName" Me.textBoxFileName.Size = New System.Drawing.Size(280, 20) Me.textBoxFileName.TabIndex = 5 Me.textBoxFileName.Text = "" ' 'buttonUp ' Me.buttonUp.Location = New System.Drawing.Point(256, 72) Me.buttonUp.Name = "buttonUp" Me.buttonUp.Size = New System.Drawing.Size(32, 23) Me.buttonUp.TabIndex = 4 Me.buttonUp.Text = "up" ' 'formSave ' Me.AcceptButton = Me.buttonOk Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.CancelButton = Me.buttonCancel Me.ClientSize = New System.Drawing.Size(298, 250) Me.Controls.AddRange(New System.Windows.Forms.Control() _ {Me.labelSaveTo, Me.textBoxFileName, Me.label2, Me.buttonUp, _ Me.listBoxDirectories, Me.label1, Me.buttonOk, Me.buttonCancel}) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog Me.Name = "formSave" Me.Text = "Save Text File" Me.ResumeLayout(False) End Sub Private Sub formSave_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'purpose: load the form 'local scope 'load the directory list box Call loadDirListBox() End Sub Private Sub loadDirListBox() 'purpose: load the list box control based on the current path ' note: this procedure is the same as the one in formOpen 'local scope Dim myDirectory As System.IO.DirectoryInfo Dim myDirectories() As System.IO.DirectoryInfo Dim i As Integer 'clear the directory list box listBoxDirectories().Items().Clear() 'create a new directory object myDirectory = New System.IO.DirectoryInfo(path:=myPath) 'return the sub directories from the global directory object myDirectories = myDirectory.GetDirectories() 'loop through the directories and add them to the list box For i = 0 To UBound(myDirectories) - 1 'add the directory name to the list listBoxDirectories().Items.Add(myDirectories(i).Name) Next 'select the first directory in the list ' note: this will trigger the events that fill the label control ' and the files list box and its label control If listBoxDirectories().Items.Count > 0 Then listBoxDirectories().SelectedIndex = 0 End If End Sub Private Sub listBoxDirectories_SelectedIndexChanged( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles listBoxDirectories.SelectedIndexChanged 'purpose: update the directory name when users select a directory 'local scope 'set the directory's name myDirName = listBoxDirectories().SelectedItem.ToString & "\" 'reset the save to directory labelSaveTo().Text = myPath & myDirName End Sub Private Sub buttonUp_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles buttonUp.Click 'purpose: move back one directory ' note: this proc. is the same as formOpen 'local scope Dim intPos As Integer 'find the \ at the end of the path intPos = InStrRev(stringCheck:=Mid(myPath, 1, Len(myPath) - 1), _ stringMatch:="\") If intPos = 0 Then 'no more path info Beep() Else 'trim the path back myPath = Mid(myPath, 1, intPos) Call loadDirListBox() End If End Sub Private Sub listBoxDirectories_DoubleClick(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles listBoxDirectories.DoubleClick 'purpose: manange the double-click event ' which allows users to navigate down directories ' note: same as formOpen's 'local scope 'set the new global path myPath = myPath & myDirName 'reset the selected directory to nothing myDirName = "" 'update the list directory list box Call loadDirListBox() End Sub Private Sub buttonOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonOk.Click 'purpose: user has indicated they would like to apply their 'selections 'local scope Dim fileName As String 'get the file name fileName = Trim(textBoxFileName().Text) 'validate filename If fileName = "" Then 'raise a message to the user MsgBox(prompt:="Please enter a file name.", _ buttons:=MsgBoxStyle.Exclamation, title:="FontPad Save") 'position cursor textBoxFileName().Focus() Else 'check the file name's extension If Not fileName.EndsWith(".txt") Then fileName = fileName.Insert(fileName.Length, ".txt") End If 'call save file method Call saveFile(fileName:=fileName) 'close the form Me.Close() End If End Sub
The primary piece of functionality (save) can be found in the saveFile procedure. First, we use methods of the File class to determine if the file already exists. If a file does exist, we handle the situation by first deleting it and then saving it as new. This is a shortcut and not the best solution. A more robust design would tell the user the file already exists and prompt him to overwrite. Next, we create the FileStream object to write out the file. We open a StreamWriter instance and set it to start writing at the beginning of our file. After this, we call the Write method and pass it our contents as a string value. Finally we Flush and Close the StreamWriter instance. Our new file is now saved to disk.
Private Sub saveFile(ByVal fileName As String) 'purpose: save the contents of the rtb to a file 'local scope Dim fileStream As IO.FileStream Dim streamWriter As IO.StreamWriter Dim filePath As String 'set the full path of the file filePath = myPath & myDirName & fileName 'check if the file already exists in the directory If IO.File.Exists(path:=filePath) Then 'the file already exists, we cheat and delete it IO.File.Delete(path:=filePath) End If 'create a new instance of the file stream object 'note: if the file does not exist, the constructor will create it fileStream = New IO.FileStream(path:=filePath, _ mode:=IO.FileMode.OpenOrCreate, access:=IO.FileAccess.Write) 'create an instance of a character writer streamWriter = New IO.StreamWriter(stream:=fileStream) 'set the file pointer to the end of the file streamWriter.BaseStream.Seek(offset:=0, origin:=IO.SeekOrigin.Begin) 'write a line of text to the end of the file streamWriter.Write(value:=textContents) 'apply the update to the file streamWriter.Flush() 'close the stream writer streamWriter.Close() 'close the file stream object fileStream.Close() End Sub #End Region End Class