2. Introduction
• File I/O in C++ is a relatively straightforward affair.
• For the most part.
• Almost all I/O in C++ is handled via streams.
• Like cin and cout
• Random access files also supported.
• Not our focus.
• Concept complicated slightly by the presence of objects.
• Require a strategy to deal with object representation.
3. Stream I/O
• Stream I/O is the simplest kind of I/O
• Read in sequences of bytes from a device.
• Write out sequences of bytes to a device
• Broken into two broad categories.
• Low level I/O, whereby a set number of bytes are transferred.
• No representation of underlying data formats
• High level I/O
• Bytes are grouped into meaningful units
• Such as ints, chars or strings
4. Random Access Files
• Sequential files must be read in order.
• Random access files permit non-sequential access to data.
• System is considerably more complicated.
• Must have a firm definition of all data attributes.
• Issue complicated by the presence of ‘non-fixed length’ data
structures.
• Such as strings.
• Must work out the size of a record on disk.
5. Basic File I/O - Output
• Straightforward process
• #include <fstream>
• Instantiate an ofstream object
• Use it like cout
• Close in when done:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream out("blah.txt");
out << "Hello World" << endl;
out.close
return 0;
}
6. Basic File I/O - Input
• Same deal
• Use a ifstream object
• Use it like cin
• Close when done
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream in("blah.txt");
string bleh;
in >> bleh;
cout << bleh;
in.close();
return 0;
}
7. The Process
• A file in C++ has two names.
• The name it has in the directory structure.
• Such as c:/bing.txt
• The name it has in the object you create in your C++ program.
• The link between the two is forged by the creation of a stream
object.
• This creates the connection between the two.
8. The Process
• We must close files when we are finished with them.
• Signifies to the O/S that we are done with the file.
• Flushes all remaining file accesses and commits them to the file.
• Releases the resources in our system.
• We need to do this regardless of whether it is an input or an
output operation.
9. Stream Objects
• The constructor for a stream object can take a second
parameter.
• The type of mode for the I/O
• These are defined in the namespace ios:
• ofstream out ("blah.txt", ios::app);
• Used for specialising the type of stream.
• Above sets an append.
• Others have more esoteric use.
10. So Far, So Good…
• Limited opportunities for expression with this system.
• Need more precision on representation of data
• There exist a range of stream manipulators that allow for fine-
grained control over stream I/O
• dec
• hex
• octal
• setbase
11. Stream Manipulators
• These work on simple screen/keyboard I/O and file I/O
• They make use of the Power of Polymorphism
• They are defined in the std namespace.
• Inserted into the stream where needed. Acts on the stream from
that point onwards.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
cout << oct << 10;
return 0;
}
12. Stream Manipulators
• Some stream manipulators are parameterized
• Like setbase
• These are called parameterized stream manipulators
• They get defined in iomanip.h
• When used, they must be provided with the parameter that
specialises their behaviour.
• setbase takes one of three parameters
• 10, 8 or 16
13. Precision
• One of the common things we want to be able to do with
floating point numbers is represent their precision.
• Limit the number of decimal places
• This is done using the precision method and the fixed stream
manipulator.
• Precision takes as its parameter the number of decimal places to
use.
15. Width
• We can use the width method to set the maximum field width
of data.
• This is not a sticky modifier
• Impacts on the next insertion or extraction only.
• It does not truncate data
• You get the full number.
• It does pad data
• Useful for strings.
• Defaults to a blank space. Can use the setfill modifier to change the
padding character.
16. Other Stream Manipulators
• showpoint
• Shows all the trailing zeroes in a floating point number.
• Switched off with noshowpoint
• Justification
• Used the parameterized setw to set the width of the of the value
• Use left or right to justify
• Default is right jutsification
• Research these
• Quite a lot to handle various purposes.
17. Reading In A Paragraph
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main() {
ifstream in ("blah.txt");
string str;
in >> str;
while (!in.eof()) {
cout << str << " ";
in >> str;
}
return 0;
}
18. Buffering
• The files that exist on the disk do not necessarily reflect the
information we have told C++ to write.
• Why?
• The answer is down to buffering.
• File IO is one of the most expensive procedures in executing a
program.
• C++ will try to keep the I/O costs down as far as possible through
buffering.
19. What’s In A File Access?
• File Accessing is broken down into two main stages.
• Seeking the file
• Interacting with the file.
• Imagine 500 instructions to write to a file.
• 500 seeks, 500 writes
• Buffering maintains an internal memory cache of write
accesses.
• Reduce down to 1 seek.
20. Buffering
• The file is updated under the following circumstances:
• When the file is closed.
• Thus, one of the reasons why we must close our files.
• When the buffer is full.
• Buffers are limited in size, and are ‘flushed’ when that size is
reached.
• When you explicitly instruct it.
• Done sometimes with manipulators (such as endl)
• Done using the sync method of the stream.
21. Summary
• File I/O in C++ is handled in the same way as
keyboard/monitor I/O
• At least as far as stream-based IO is concerned.
• Stream I/O is very versatile in C++
• Handled through stream manipulators
• File accesses in C++ are, as far as is possible, buffered.
• This greatly reduces the load on the hardware.