Transcript CHAPTER 10

Lecture Set 12
Sequential Files and Structures
Part B – Reading and Writing
Sequential Files
Objectives


Learn about the classes that support file
input/output
Understand the concept of abstraction and
how it related to the file I/O model



Connecting files and streams
Learn how to read sequential text files
Learn how to write sequential text files


Text files = streams of characters perhaps
with special characters (often the end of line
character) that mark the end of a line.
Always “marked” with an end of file
7/7/2015 12:05 PM
Classes that Support (Text) File I/O

System.IO classes used to work with drives
and directories




Directory
File
Path
A statement that simplifies references to the
System.IO classes

Imports System.IO
7/7/2015 12:05 PM
The Directory Class

Common methods of the Directory class




Exists (path designation)
CreateDirectory (path designation)
Delete (path designation)
Code that uses some of the Directory methods
string dir = "C:\CS 2010\Files\“;
if (! Directory.Exists(dir))
Directory.CreateDirectory(dir);
7/7/2015 12:05 PM
The File Class

Common methods of the File class





Exists (path)
Delete (path)
Copy (source, dest)
Move (source, dest)
Code that uses some of the File methods
string path = dir + "Products.txt“;
if (File.Exists(path))
File.Delete(path);
7/7/2015 12:05 PM
Introduction to Files and Streams



System.IO classes are used to work with files
and streams
You can work with two kinds of files – text files
(containing only characters) and binary files
In this Lecture Set, we discuss text files in detail
– we present material on binary files later but
will not discuss them in this course
7/7/2015 12:05 PM
Text vs Binary Files
A text file displayed in a text editor
A binary file displayed in a text editor
7/7/2015 12:05 PM
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 in every record
There are other types of files in addition to sequential
files: binary files; direct (random or indexed) access files
7/7/2015 12:05 PM
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-bycharacter or all at once
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
Delimited Sequential File
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
Fixed-field File
7/7/2015 12:05 PM
An Underlying Framework

To be visited three times




In understanding file manipulation
In understanding database manipulation
In understanding graphics
But, in fact, you have already studied this
framework many times as far back as your
first course – it is the Object-Oriented
Framework
7/7/2015 12:05 PM
The Object Framework 1
In your programs, you
manipulate objects using
methods belonging to the class
that defines the type of the
object
 The class is an abstraction
(model) of the object being
manipulated

7/7/2015 12:05 PM
The Object Framework 2


So it is only natural that the manipulation of
files, databases, graphics, and other entities
such as collections (be they arrays, strings,
lists of objects, or whatever) follow this
object-oriented framework
We are particularly interested in manipulating
files (this Lecture Set), databases (Lecture
Set 14) and graphics (Lecture Set 13)
7/7/2015 12:05 PM
The Object Framework 3


In all these cases, we must …
Design and implement a class to model the
entity to be manipulated




We often refer to such a class as an abstraction
of the object, encapsulating the data stores and
methods that are required
The class is said to define an “abstract data
type”
We can then create objects (instances of the
class we just created)
Next comes the tricky part … 
7/7/2015 12:05 PM
The Object Framework 4




We now have to connect that object to the actual
entity to be manipulated
1. For files, the object is an instance of a class that
provides an abstract view of a file. This view is
modeled by a Stream class (StreamReader or
StreamWriter classes).
2. For databases, the object is an instance of a class
that provides an abstract view of a database. This
view is modeled by the OledbConnection class.
3. For graphics the object is an instance of a class
that provides an abstract view of a graphics entity
such as a drawing. This view is modeled by the
Graphics class (see Lecture Set 13).
7/7/2015 12:05 PM
The Object Framework 5 – Why Bother




Why do this – what is this all about?
First – it is not new – goes way back to
efforts in C++ (for example) to build an
abstraction of a file
The abstraction enables us to manipulate files
(text files in our case) in a uniform, consistent
way, regardless of the underlying structure of
the file or the operating system that manages
the file
The underlying structure is hidden under
several layers of software
7/7/2015 12:05 PM
The Object Framework 6 – Why Bother

Programmer layer – read (write) data to (from)
individual program variables or objects
programmer variables
write
↓
read
↑
streams

Logical layer – manages the buffering of data as it
is read or written
streams
write
↓
read
↑
physical files

Physical layer – manages the actual (physical)
transmission of data from a physical file to or from
the buffer in memory
7/7/2015 12:05 PM
The Object Framework 7 – Why Bother


The central issue is this: Your programming
task is made easier because …
You program against a (generalized)
abstraction of a real “thing” and not against
the thing itself.


You do not need to worry about the details of
the underlying file but just the methods and
properties provided to you by the abstraction
(the given stream class)
So? What are these methods and properties?

7/7/2015 12:05 PM
The Object Framework 8 – The Connection
The stream abstraction
(methods and data
stores) of a file that you
program against
(reading and writing an
entire file, a line at a
time, or a field at a time)
The
connection –
The actual,
physical file to be
manipulated
via creation of a
streamReader or
streamWriter
object
'Create instance of StreamReader class (type) and store ref
dictionarySR = new System.IO.StreamReader("DictionaryFile.txt");
7/7/2015 12:05 PM
The Stream-File Connection


What we see here is an abstraction for
handling both binary and text files
The abstraction is the stream

When you program the manipulation of files, you
are really programming “against” the stream
abstraction:





FileStream
StreamReader
StreamWriter
BinaryReader
BinaryWriter
7/7/2015 12:05 PM
Establishing Connections


There are several different ways to establish
file-stream connections
Create a FileStream object
string path = “C:\VB 2005\Files\Products.txt;
FileStream fs = new FileStream(path, FileMode.create,
FileAccess.Write);



Create a StreamReader object
Create a StreamWriter object
The results of using these techniques are
similar – they all result in the creation of (or
opening of) a stream (fs) against which all
subsequent file operations are written
7/7/2015 12:05 PM
Connecting Sequential Files and Streams




The files we use exist in some external location
Internally, in our program, the contents of these files are
manipulated as streams
Before we can perform these manipulations, we have to connect the
file to the stream
In VB we do that when we create an instance of a StreamReader
object
System.IO.StreamReader currentReader;
currentReader = new System.IO.StreamReader(“C:\MyText.txt”);
External file, such as
dictionaryFile.txt
Connecting an external file
to a program (variable)
Internal information about
the external file needed
for the program to connect
the file to a stream object
(Example: The
streamReader object
dictionarySR)
The FileStream Class 1
The syntax for creating a FileStream object
new FileStream(path, mode[, access[, share]])
Members in the FileMode enumeration
• Append – opens a file if it exists and place the write pointer at
the end of the file
• Create – Creates a new file. If file exists it is overwritten
• CreateNew – Creates a new file. If file already exists an
exception is thrown
• Open – Opens an existing file. If file does not exist, an
exception is thrown
• OpenOrCreate – Opens a file if it exists or creates a new file if
it does not exist
• Truncate –Opens an existing file and truncates it to zero bytes
(erases its contents)
7/7/2015 12:05 PM
The FileStream Class 2
Members in the FileAccess enumeration
Read
ReadWrite
Write
Members in the FileShare enumeration
None
Read
ReadWrite
Write
Common method of the FileStream class
Close()
7/7/2015 12:05 PM
The Exception Classes For File I/O
 IOException
 DirectoryNotFoundException
 FileNotFoundException
 EndOfStreamException
Code That Uses Exception Classes
string dirPath = "C:\CS 2010\Files\";
string filePath = dirPath + "Products.txt";
FileStream fs;
try
{
fs = new FileStream(filePath, FileMode.Open)
// code that uses the file stream
// to read and write data from the file
}
catch (FileNotFoundException fnf)
MessageBox.Show(filePath & " not found.",
"File Not Found");
catch (DirectoryNotFoundException dnf)
MessageBox.Show(dirPath & " not found.",
"Directory Not Found");
catch (IOException ioe)
MessageBox.Show(ioe.Message, "IOException");
finally
if fs != Null) fs.Close();
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
7/7/2015 12:05 PM
The StreamReader Constructor (Syntax)

public StreamReader(string path)

The StreamReader constructor accepts one
argument – the path and filename of the
sequential file to open (see previous slide)
7/7/2015 12:05 PM
Why Have Connections – Who Cares?


Software (and Ogres) have layers
Why do they have layers


Hiding lower level details from mid level details
from user level details
Example – input/output

Physical layer –


Transmit information between external file and
internal memory (buffers)
Remembering where you are in terms of the last
read or write to a file (buffer pointer manipulation)
7/7/2015 12:05 PM
Why Have Connections – Part 2

I/O Layers (continued)

Logical layer (data input)–



Transmit characters to a buffer (memory) stream,
convert to correct data type and store in
programmers variables (objects)
Remembering where you are in terms of the last
transmission/conversion (more buffer pointer
manipulation)
Programmer Layer

Manipulate data in internal format as needed in
program
7/7/2015 12:05 PM
Why Have Connections – Part 3

Layered software for Input/Output
In the code below, myDictionaryStream contains a string of words (separated by blanks)
as read directly from a text file. The Split method will use the blank to separate these words
and store them one at a time in the array myDictionaryWords.
private string myDictionaryStream;
// Dictionary as read as string
private int myDictionarySize;
// Dictionary size
// Dictionary as array of strings used for Split method
private string [] myDictionaryWords;
. . .
// Parse and Store Words in Dictionary
//
Returns number of words picked up
private void ParseAndStoreWords(string myDictionaryStream)
{
char delimiter = ' ';
myDictionaryWords = myDictionaryStream.Split(delimiter);
myDictionarySize = myDictionaryWords.GetLength(0);
} // end ParseAndStoreWords
This code gets a line of information from a file buffer (myDictionaryStream ), splits line
using a delimiter of a blank, and stores the converted four values in the fields of a structure.
7/7/2015 12:05 PM
The StreamReader Constructor


(Example)
We have already seen the code below
It is used to open a file named
"C:\Demo.txt“ and connect the file to the
internal StreamReader object, a stream
named CurrentReader
System.IO.StreamReader currentReader =
new System.IO.StreamReader("C:\Demo.txt");
7/7/2015 12:05 PM
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();
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
The StreamReader Class

The ReadLine method reads a record



(Members, continued)
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
7/7/2015 12:05 PM
Reading the Entire Contents of a File



(Example)
Read the file named "C:\Demo.txt“
Where is the data stored?
What does it look like (internally)
string currentString;
StreamReader currentReader = new
StreamReader("C:\Demo.txt")
currentString = currentReader.ReadToEnd();
currentReader.Close();
7/7/2015 12:05 PM
Reading the Entire Contents of a File
(Hangman Example)

Reading from the dictionary file
private string myDictionaryStream;
// Dictionary as read as string
private int myDictionarySize;
// Dictionary size
// Dictionary as array of strings used for Split method
private string [] myDictionaryWords;
. . .
'Open and read dictionary
// Open and read dictionary
private string OpenAndReadDictionaryFile()
{
// Create object (ref) variable of type StreamReader
string myDictionaryStream;
System.IO.StreamReader dictionarySR; // Ref variable of typeSR
// Create instance of StreamReader class (type) and store ref
dictionarySR = new System.IO.StreamReader("DictionaryFile.txt");
myDictionaryStream = dictionarySR.ReadToEnd();
if (myDictionaryStream == null)
{
MessageBox.Show("Dictionary File was empty. Terminate.");
} // end If
return (myDictionaryStream);
} // end OpenAndReadDictionary
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
Flowchart to
Read a Sequential
File Character
by Character
7/7/2015 12:05 PM
Reading a Sequential File Character by
Character (Example)
char currentChar;
StreamReader currentReader = new
StreamReader("C:\Demo.txt");
currentChar = currentReader.Read();
do
{
// Statements to process the character.
currentChar = CurrentReader.Read();
}
while (currentChar != ‘$’);
currentReader.Close();
7/7/2015 12:05 PM
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
This is not a new pattern – you should have
seen and used this pattern often before
7/7/2015 12:05 PM
Reading a
Sequential File
as a List
of Records
7/7/2015 12:05 PM
Reading a Sequential File as a Stream of
Records (Example)
System.IO.StreamReader currentReader = new
System.IO.StreamReader("C:\Demo.txt");
string currentRecord;
currentRecord = currentReader.ReadLine();
do
{
// Statements to process the current record.
CurrentRecord = CurrentReader.ReadLine()
}
while (currentRecord != Null)
currentReader.Close();
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
Splitting a Text Line
(see also Slide 34)
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
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:
System.IO.StreamWriter currentWriter = new
System.IO.StreamWriter("C:\Demo.txt");
// Statements to write the file.
currentWriter.Close();
7/7/2015 12:05 PM
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
If the data type passed to Write or WriteLine is not
a string, these methods will call toString

Individual variables must be concatenated and separators
must be used
7/7/2015 12:05 PM
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
7/7/2015 12:05 PM
Writing a Delimited File

(Example)
Write an array of Integers
public void WriteIntegerList
(int [] argArray, string argFile)
{
StreamWriter currentStream = new
StreamWriter(argFile);
for (int currentIndex = 0;
currentIndex < argArray.GetUpperBound(0);
currentIndex++)
{
CurrentStream.Write(argArray(CurrentIndex));
if (currentIndex <> argArray.GetUpperBound(0))
CurrentStream.Write(",");
} // end for loop
currentStream.Close();
} // end WriteIntegerList
7/7/2015 12:05 PM
Objectives (postscript)
Knowledge
 Distinguish between a text file and a binary file.
 Describe the use of FileStream, StreamReader, StreamWriter,
BinaryReader, and BinaryWriter objects.
 Describe two common types of I/O exceptions.
 Describe the use of the My.Computer.FileSystem object.
 We will give you a complete class for reading from an input text
file when we get to the ATM Project