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