Title: File IO Input Output
 1File IO (Input Output)
 Slides 41 to 50 are new! Chapter 9 of the 
book Read sections 9.1 and 9.2 
 2Up to this point, we have either hard coded the 
information our program used (as below), or lost 
all information once the program closed Most 
real programs dont do this. Typically programs 
read in information from files, process the 
information, and write information back to files.
Consider a word processor We might run the 
Notepad program We then might open a file, say a 
homework We might process the file, say edit it, 
or run a spell check When we are done, we would 
save the file
 Dim strLastNames() As String  "GUNOPULOS", 
"PApadopoulos", "Keogh", "vlachos" Dim 
strFirstNames() As String  "dima", "JoHn", 
"Keogh", "MARY" Dim blnIsMale() As Boolean  
True, True, True, False Dim sngGPA() As Single 
 1.2, 2.4, 4.0, 3.4 
 3- With Visual Basic, we can open all kinds of 
 files, including sound files, movie files,
 webpages, spreedsheets etc.
- However, we will only consider simple, structured 
 text files
- By structured I mean that the file has well 
 defined conventions.
- For example 
-  One person per row 
-  Exactly 4 fields 
-  Order is, last name, first name, sex, GPA 
-  Missing values are denoted as _at__at_ 
-  The last name is exactly 25 characters long 
-  
 Dim strLastNames() As String  "GUNOPULOS", 
"PApadopoulos", "Keogh", "vlachos" Dim 
strFirstNames() As String  "dima", "JoHn", 
"Keogh", "MARY" Dim blnIsMale() As Boolean  
True, True, True, False Dim sngGPA() As Single 
 1.2, 2.4, 4.0, 3.4 
 4A Padded File
Note that these are spaces, NOT tabs
Note that file ends here 
 5C\Documents and Settings\eamonn.keogh\Desktop\Stu
dentData.txt
My file has a path and name. Note that the name 
includes the extension, in this case .txt 
 6Imports System.IO 
 7Dim myStream As New FileStream("C\Documents and 
Settings\eamonn.keogh\Desktop\StudentData.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Dim 
strTempString As String strTempString  
myStreamReader.ReadLine() bntRedDemo.Text  
strTempString 
 8Dim myStream As New FileStream("StudentData.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Dim 
strTempString As String strTempString  
myStreamReader.ReadLine() bntRedDemo.Text  
strTempString 
A little trick, if you dont give the path, VB 
assumes that the file is in the same directory as 
the program itself.  
 9Dim myStream As New FileStream("StudentData.txt", 
FileMode.Open, FileAccess.Read)
This line of code opens the file, read for some 
action. Why must we explicitly open (and close) 
files?
The file action
The file mode
Append Opens the file if it exists and seeks to 
the end of the file, or creates a new file. Only 
works in conjunction with FileAccess.Write. Create
 Specifies that the operating system should 
create a new file. Overwrites the file if it 
exists. CreateNew Specifies that the operating 
system should create a new file. If the file 
exists, an error occurs. Open Specifies that the 
operating system should open an existing 
file. OpenOrCreate Specifies that the operating 
system should open a file if it exists 
otherwise, a new file should be 
created. Truncate Specifies that the operating 
system should open an existing file and clear its 
contents. 
Read Data can be read from the file. Combine with 
Write for read/write access. ReadWrite Data can 
be written to and read from the file. Write Data 
can be written to the file. 
The path and name of the file to open 
 10Dim myStream As New FileStream("StudentData.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Dim 
strTempString As String strTempString  
myStreamReader.ReadLine() bntRedDemo.Text  
strTempString
If I wanted to write data to the stream, I would 
use Dim myStreamReader As New StreamWriter(myStre
am) 
 11Dim myStream As New FileStream("StudentData.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Whil
e myStreamReader.Peek() ltgt -1 
bntRedDemo.Text  myStreamReader.ReadLine() 
 bntRedDemo.Refresh() 
Sleep(1000) End While
.Peek equals 1 when the end of the file is 
reached
. 
 12Dim myStream As New FileStream("StudentXX.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Whil
e myStreamReader.Peek() ltgt -1 
bntRedDemo.Text  myStreamReader.ReadLine() 
 bntRedDemo.Refresh() 
Sleep(1000) End While
File StudentXX.txt does not exist! Trying to 
open a file that does not exist causes an 
error.. Note I am using FileMode.Open, if I 
were using one of the other options  
 13 If Not (File.Exists("StudentXX.txt")) Then 
 bntRedDemo.Text  "The file does not 
exist!" Else Dim myStream As New 
FileStream("StudentXX.txt", FileMode.Open, 
FileAccess.Read) Dim myStreamReader As New 
StreamReader(myStream) While myStreamReader.Peek
() ltgt -1 bntRedDemo.Text  
myStreamReader.ReadLine() 
bntRedDemo.Refresh() 
Sleep(1000) End While End If
I wont show this test for existence in future 
slides (to save space ), but it is always our 
responsibility to test for a files existence 
before opening it. 
 14Dim myStream As New FileStream("StudentData.txt", 
FileMode.Open, FileAccess.Read) Dim 
myStreamReader As New StreamReader(myStream) Whil
e myStreamReader.Peek() ltgt -1 
bntRedDemo.Text  myStreamReader.ReadLine() 
 bntRedDemo.Refresh() 
Sleep(1000) End While myStream.Close() myStreamRe
ader.Close()
We need to close files/streams as soon as we are 
done with them 
 15So far we have been reading files a whole line at 
a time, as a single string. We need to be able 
to get at individual parts 
 16Last names begin at 0
First names begin at 24
Sex begins at 40
The last line is for demonstration only. Dont 
add such a line to your code
GPA begins at 48 
 17 Dim strTempString, strLName, strFName, 
strSex As String Dim sngGPA As Single 
 strTempString  myStreamReader.ReadLine() 
 strLName  Trim(strTempString.Substring(0, 
24)) strFName  Trim(strTempString.Substri
ng(24, 16)) strSex  Trim(strTempString.Su
bstring(40, 8)) sngGPA  
Val(strTempString.Substring(48, 3)) If 
UCase(strSex)  "M" Then 
bntRedDemo.Text  "Mr. "  strFName  " "  
strLName  " has a GPA of "  Str(sngGPA) 
Else bntRedDemo.Text  "Ms. "  
strFName  " "  strLName  " has a GPA of "  
Str(sngGPA) End If
Raw data
One problem with the above is magic numbers 
 18Up to now we have been working with padded files 
(also called fixed width files), let us now 
consider comma delimited files. 
 19Important note! My way of dealing with comma 
delimited files is different to way given in the 
book. Ignore the book on comma delimited files 
(Section 9.3) 
 20There is nothing magic about commas. We could us 
other character, so long as it does not appear in 
any of the fields. The separator is sometimes 
called an escape character.
- Padded Files vs Comma Delimited files. 
-  
-  Padded files are easier for humans to read. 
-  Padded files require that we have a maximum 
 length for each field.
-  Comma Delimited files take up less space. 
-  Comma Delimited files do not allow random access 
 (Explanation later)
21 Dim myStream As New FileStream("StudentDat
a2.txt", FileMode.Open, FileAccess.Read) 
Dim myStreamReader As New StreamReader(myStream) 
 Dim strTempString, strLName, strFName, 
strSex As String Dim sngGPA As Single 
 strTempString  myStreamReader.ReadLine() 
 bntRedDemo.Text  strTempString 
 myStream.Close() myStreamReader.Close()
We can read comma delimited files, just like we 
read padded files But we cannot extract the 
fields in the same way.  
 22Review, we have seen this slide before
There is a function called InStr, which looks for 
a substring in a longer string, and returns its 
location
Function Name InStr Function Description 
Returns the position of the first occurrence of a 
substring that is searched for in the String 
passed. Common Uses InStr can be used to tell us 
if a String has a certain substring contained 
within it. It operates much like searching a 
document for a word. Syntax Long  InStr(String 
to be Searched, Search String) Examples
Syntax Integer  InStr(String,String) 
 23There is a function called Mid, which returns a 
subsection of a string
Review, we have seen this slide before
Returns a specific number of characters of a 
String allowing the developer to indicate where 
to start and how many characters to return. The 
first parameter is the source String. The second 
is an Integer indicating the starting position to 
copy from. The third parameter is optional and 
indicates the number of characters to copy. If 
the third parameter is left out, all characters 
from the starting position are returned.
Syntax String  Mid(String, integer_type, 
integer_type )
Optional!  
 24 strTempString  myStreamReader.ReadLine() 
bntRedDemo.Text  InStr(strTempString, ",")
This is a little cryptic.. (see next slide) 
 25Const mySEPARATOR  "," strTempString  
myStreamReader.ReadLine() bntRedDemo.Text  
InStr(strTempString, mySEPARATOR) 
 26Lets work on just getting the first field
Dim shtFrom, shtLen As Short strTempString  
myStreamReader.ReadLine() shtFrom  1 shtLen  
InStr(strTempString, mySEPARATOR) strLName  
Mid(strTempString, shtFrom, shtlen) bntRedDemo.Tex
t  strLName
This is almost right, but we have one extra 
character 
 27This works
Dim shtFrom, shtLen As Short strTempString  
myStreamReader.ReadLine() shtFrom  1 shtLen  
InStr(strTempString, mySEPARATOR) - 1 strLName  
Mid(strTempString, shtFrom, shtLen) bntRedDemo.Tex
t  strLName 
 28- We can pull out the first field because we know 
-  Where it begins, at 1 
-  Where it ends, at the first comma (-1)
shtFrom  1 shtLen  InStr(strTempString, 
mySEPARATOR) - 1 strLName  Mid(strTempString, 
shtFrom, shtLen)
GUNOPULOS,dima,M,1.2
What about the second field? We know the 
beginning, it is just the end of the previous 
field, plus two. However, we dont have an easy 
way to get the end 
 29Dim shtFrom, shtLen As Short strTempString  
myStreamReader.ReadLine() shtFrom  1 shtLen  
InStr(strTempString, mySEPARATOR) - 1 strLName  
Mid(strTempString, shtFrom, shtLen) 
strTempString  Mid(strTempString, shtlen  2) 
shtlen  InStr(strTempString, mySEPARATOR) - 1 
strFName  Mid(strTempString, shtFrom, shtlen) 
bntRedDemo.Text  "Mr. "  strFName  " "  
strLName
GUNOPULOS,dima,M,1.2
dima,M,1.2 
 30GUNOPULOS,dima,M,1.2
dima,M,1.2
- This is our basic trick for reading comma 
 delimited files.
- We read an entire line. 
-  We read the first field (up to the first comma). 
-  We remove the first field (plus the first comma) 
- If we are not done, we go back to step one
M,1.2
1.2 
 31strTempString  myStreamReader.ReadLine() shtFrom 
 1 shtLen  InStr(strTempString, mySEPARATOR) - 
1 strLName  Mid(strTempString, shtFrom, shtLen) 
 strTempString  Mid(strTempString, shtlen  
2) shtlen  InStr(strTempString, mySEPARATOR) - 
1 strFName  Mid(strTempString, shtFrom, 
shtlen) strTempString  Mid(strTempString, 
shtlen  2) shtlen  InStr(strTempString, 
mySEPARATOR) - 1 strSex  Mid(strTempString, 
shtFrom, shtlen) 
GUNOPULOS,dima,M,1.2
dima,M,1.2
M,1.2
Note the repetition in the code, we can simply 
cut and paste the block of 3 lines of code, 
changing on the variable name of the field (we 
could push these 3 lines into a function)  
 32strTempString  Mid(strTempString, shtlen  
2) shtlen  InStr(strTempString, mySEPARATOR) - 
1 strFName  Mid(strTempString, shtFrom, 
shtlen) strTempString  Mid(strTempString, 
shtlen  2) shtlen  InStr(strTempString, 
mySEPARATOR) - 1 strSex  Mid(strTempString, 
shtFrom, shtlen) strTempString  
Mid(strTempString, shtlen  2) sngGPA  
Mid(strTempString, shtFrom)
dima,M,1.2
M,1.2
1.2
The last field is special, because the end is not 
marked with a comma, we just take the entire 
string We could write this as one line sngGPA 
 Mid(strTempString, shtlen  2) 
 33. . 
 34So far we have read files, printed them out one 
line at a time and immediately forgotten the 
information! More realistically, we would want 
to keep all the data around to process it (sort 
it, update the GPAs, look for a particular 
person, look for the lowest GPA) How to we keep 
lists of data? With arrays. In the past we 
hardcoded arrays (as below), but now we can 
populate arrays by reading files.
 Dim strLastNames() As String  "GUNOPULOS", 
"PApadopoulos", "Keogh", "vlachos" Dim 
strFirstNames() As String  "dima", "JoHn", 
"Keogh", "MARY" Dim blnIsMale() As Boolean  
True, True, True, False Dim sngGPA() As Single 
 1.2, 2.4, 4.0, 3.4 
 35Note that little has changed from the previous 
code 
 36Note the order, you cannot reverse it 
 37(No Transcript) 
 38Wrong sex 
 39(No Transcript) 
 40Padded files allow random access. Comma 
delimited files require sequential access  
 41Writing padded files 
 42Review, we have seen this slide before
Last names begin at 0
First names begin at 24
Sex begins at 40
The last line is for demonstration only. Dont 
add such a line to your code
GPA begins at 48 
 43Dim strTempString As String strTempString  
Eamonn strTempString  strTempString.PadRight 
The variable strTempString now has the value 
Eamonn  Note the four extra spaces. There 
is also a PadLeft function  
 44 Dim strTempString, strLName, strFName, 
strSex As String Dim sngGPA As Single 
 strTempString  myStreamReader.ReadLine() 
 strLName  Trim(strTempString.Substring(0, 
24)) strFName  Trim(strTempString.Substri
ng(24, 16)) strSex  Trim(strTempString.Su
bstring(40, 8)) sngGPA  
Val(strTempString.Substring(48, 3)) If 
UCase(strSex)  "M" Then 
bntRedDemo.Text  "Mr. "  strFName  " "  
strLName  " has a GPA of "  Str(sngGPA) 
Else bntRedDemo.Text  "Ms. "  
strFName  " "  strLName  " has a GPA of "  
Str(sngGPA) End If
Raw data
One problem with the above is magic numbers
Review, we have seen this slide before 
 45Dim myOutStream As New FileStream("StudentDataNew2
.txt", FileMode.Create, FileAccess.Write) Dim 
myStreamWriter As New StreamWriter(myOutStream) 
For shtIndex  0 To UBound(strLastNames) 
 If blnIsMale(shtIndex) Then 
strTempString  strLastNames(shtIndex).PadRight(23
) strTempString  
strFirstNames(shtIndex).PadRight(16) 
 strTempString  ("M").PadRight(8) 
 strTempString  sngGPA(shtIndex).ToString() 
 Else strTempString  
strLastNames(shtIndex).PadRight(23) 
 strTempString  strFirstNames(shtIndex).PadRigh
t(16) strTempString  
("F").PadRight(8) strTempString 
 sngGPA(shtIndex).ToString() End 
If myStreamWriter.WriteLine(strTempSt
ring) Next myStreamWriter.Close() 
 myOutStream.Close() 
 46Dim myOutStream As New FileStream("StudentDataNew2
.txt", FileMode.Create, FileAccess.Write) Dim 
myStreamWriter As New StreamWriter(myOutStream) 
For shtIndex  0 To UBound(strLastNames) 
strTempString  strLastNames(shtIndex).PadRight(23
) strTempString  strFirstNames(shtIndex).Pa
dRight(16) If blnIsMale(shtIndex) Then 
 strTempString  ("M").PadRight(8) 
 Else strTempString  
("F").PadRight(8) End If 
strTempString  sngGPA(shtIndex).ToString() 
 myStreamWriter.WriteLine(strTempString) Next 
 myStreamWriter.Close() 
myOutStream.Close()
The previous version had redundant code, this is 
better. (why is redundant code bad?)  
 47- Two possible problems. 
- A space before Eamonn, we can use trim 
- 4.0 was formatted and 4 
-  The second point could be a major problem. If 
 other programs are going to look at our file, and
 they dont automatically convert spaces to zeros
48strTempString  sngGPA(shtIndex).ToString("N1")
 We can fix the problem with a format specifier  
 49Visual Basics Format Specifiers
Specifier Name Description Code C Currency Form
ats with a dollar sign, commas, two decimal 
places Negative values are in 
() F Fixed-Point Formats as a string of numeric 
 digits, no commas, two decimal places, 
a minus sign at the left for negative 
values N Number Formats with commas, two 
 decimal places, a minus sign at the 
left for negative values D Digits Use only for 
integer data types. Formats with a left 
minus sign for negative values. P Percent 
Multiplies the value by 100, add a space and 
percent sign, and rounds to two decimal 
places 
 50Examples
Variable Value Format Output totalDecimal 1125.
6744 C 1,125.67 totalDecimal 1125.6744 N 1,125
.67 totalDecimal 1125.6744 N0 1,126 balanceDecim
al 1125.6744 N3 1,125.674 balanceDecimal 1125.674
4 F0 1,126 pinInteger 123 D6 000123 rateDecima
l 0.075 P 7.50 rateDecimal 0.075 P3 7.500 
rateDecimal 0.075 P0 8 valueInteger -10 C (
10.00) valueInteger -10 N -10.00 valueInteger 
 -10 D3 -010