550 likes | 572 Views
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
E N D
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
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
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 2012\Files\“; if (! Directory.Exists(dir)) Directory.CreateDirectory(dir);
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);
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
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 sequentialfile • 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
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 hardreturn • 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
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
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
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
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)
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 …
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).
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
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
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?
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 actual, physical file to be manipulated The connection – via creation of a streamReader or streamWriter object 'Create instance of StreamReader class (type) and store ref dictionarySR = new System.IO.StreamReader("DictionaryFile.txt"); The Object Framework 8 – The Connection
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
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
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”);
The FileStream Class 1 • The syntax for creating a FileStream object • newFileStream(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)
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()
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) • publicStreamReader(stringpath) • The StreamReader constructor accepts one argument – the path and filename of the sequential file to open (see previous slide)
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)
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
Why Have Connections – Part 3 • Layered software for Input/Output
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");
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“ • Where is the data stored? • What does it look like (internally) string currentString; StreamReader currentReader = newStreamReader("C:\Demo.txt") currentString = currentReader.ReadToEnd(); currentReader.Close();
Reading the Entire Contents of a File (Hangman Example) • Reading from the dictionary file
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
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();
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
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();
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
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: System.IO.StreamWriter currentWriter = new System.IO.StreamWriter("C:\Demo.txt"); // Statements to write the file. currentWriter.Close();