File Processing (1)
Slides version: lecture13_slides.html Website version: lecture13.html
- What is File?
- Temporary variable & Permanent file
- Example: Gradebook (Text) & Image (Binary)
- File 101 in C++
- Open & Close File
- Read or Write or Read & Write
- Text or Binary
- Append or Overwrite
- Sequantial or Random Access
- Example 1: Big Real Number in Text File
- Example 2: Point & Triangle in Text File (function ver.)
- Example 3: Vector & Matrix in Binary File (function ver.)
- Pratices
What is File?
A computer file is a computer resource for recording data in a computer storage device, primarily identified by its file name. Just as words can be written to paper, so can data be written to a computer file.
Ref: https://en.wikipedia.org/wiki/Computer_file
Example: Gradebook (Text)
In text format (csv):
Name,Grade
John,A
Mary,B
In table format:
Name | Grade |
---|---|
John | A |
Mary | B |
Example: Image (Binary)
In viewable format: as the image on the right
In binary format:
00000000: ffd8 ffe1 4812 4578 6966 0000 4d4d 002a ....H.Exif..MM.*
00000010: 0000 0008 0007 0112 0003 0000 0001 0001 ................
00000020: 0000 011a 0005 0000 0001 0000 0062 011b .............b..
00000030: 0005 0000 0001 0000 006a 0128 0003 0000 .........j.(....
00000040: 0001 0002 0000 0131 0002 0000 001c 0000 .......1........
00000050: 0072 0132 0002 0000 0014 0000 008e 8769 .r.2...........i
00000060: 0004 0000 0001 0000 00a4 0000 00d0 002d ...............-
00000070: c6c0 0000 2710 002d c6c0 0000 2710 4164 ....'..-....'.Ad
00000080: 6f62 6520 5068 6f74 6f73 686f 7020 4353 obe Photoshop CS
00000090: 3520 5769 6e64 6f77 7300 3230 3133 3a30 5 Windows.2013:0
000000a0: 343a 3031 2031 353a 3033 3a30 3400 0000 4:01 15:03:04...
000000b0: 0003 a001 0003 0000 0001 0001 0000 a002 ................
File 101 in C++
Steps to process a file:
- Open a file
- Seek to a position
- Read or write data
- Close the file
Open a file (Write)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// write to a file
// create a output file stream object
ofstream outfile;
// open a file
outfile.open("test.txt");
// check if the file is open
if (!outfile)
{
cout << "Error opening file" << endl;
return 1;
}
// ...
}
Seek to a position (Write)
int main()
{
// ...
// open a file
outfile.open("test.txt");
// ...
// seek to the end of the file
outfile.seekp(0, ios::end);
// ...
}
test.txt
:
|
Read or write data (Write)
int main()
{
// ...
// seek to the end of the file
outfile.seekp(0, ios::end);
// write to the file
outfile << "Hello World!" << endl;
// ...
}
test.txt
:
Hello World!⏎
|
Close the file (Write)
int main()
{
// ...
// write to the file
outfile << "Hello World!" << endl;
// close the file
outfile.close();
}
test.txt
:
Hello World!⏎
|<EOF>
Hello World! (Write)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// write to a file
// create a output file stream object
ofstream outfile;
// open a file
outfile.open("test.txt");
// check if the file is open
if (!outfile)
{
cout << "Error opening file" << endl;
return 1;
}
// seek to the end of the file
outfile.seekp(0, ios::end);
// write to the file
outfile << "Hello World!" << endl;
// close the file
outfile.close();
}
Open a file (Read)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// read from a file
// create a input file stream object
ifstream infile;
// open the file
infile.open("test.txt");
// or open the file with ifstream constructor
// ifstream infile("test.txt");
// check if the file is open
if(!infile)
{
cout << "Error opening file" << endl;
return -1;
}
// ...
}
Seek to a position (Read)
int main()
{
// ...
// open the file
infile.open("test.txt");
// ...
// seek to the front of the file
infile.seekg(0, ios::beg);
// ...
}
test.txt
:
|Hello World!⏎
<EOF>
Read or write data (Read)
int main()
{
// ...
// seek to the front of the file
infile.seekg(0, ios::beg);
// read the file until the end (.eof() is true)
while(!infile.eof())
{
// read a line
string line;
getline(infile, line);
// print the line
cout << line << endl;
}
// ...
}
test.txt
:
Hello World!⏎
|<EOF>
console:
$ ./a.out
Hello World!
$
Close the file (Write)
int main()
{
// ...
// read the file until the end (.eof() is true)
while(!infile.eof())
{
// read a line
string line;
getline(infile, line);
// print the line
cout << line << endl;
}
// close the file
infile.close();
}
Hello World! (Read)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// read from a file
// create a input file stream object
ifstream infile;
// open the file
infile.open("test.txt");
// or open the file with ifstream constructor
// ifstream infile("test.txt");
// check if the file is open
if(!infile)
{
cout << "Error opening file" << endl;
return -1;
}
// seek to the front of the file
infile.seekg(0, ios::beg);
// read the file until the end (.eof() is true)
while(!infile.eof())
{
// read a line
string line;
getline(infile, line);
// print the line
cout << line << endl;
}
// close the file
infile.close();
}
Open & Close File
Three ways to open a file:
- Open a file with
ofstream
(Write only) - Open a file with
ifstream
(Read only) - Open a file with
fstream
(Read & Write)
Two functions to open a file:
- Use constructor
fstream(filename, mode)
- Use function
open(filename, mode)
To close a file:
- Use function
close()
- Use destructor inplicitly
- The destructor will be called when the function returns
Open & Close a file with ofstream
(Write only)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a output file stream object
ofstream outfile;
// open a file with `.open(filename)`
outfile.open("test.txt");
// close the file
outfile.close();
// open a file with constructor `ofstream(filename)`
ofstream outfile2("test.txt");
// close the file
outfile2.close();
}
Open & Close a file with ifstream
(Read only)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object
ifstream infile;
// open a file with `.open(filename)`
infile.open("test.txt");
// close the file
infile.close();
// open a file with constructor `ifstream(filename)`
ifstream infile2("test.txt");
// close the file
infile2.close();
}
Open & Close a file with fstream
(Read & Write)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object
fstream file;
// open a file with `.open(filename)`
file.open("test.txt");
// close the file
file.close();
// open a file with constructor `fstream(filename)`
fstream file2("test.txt");
// close the file
file2.close();
}
Check if the file is open
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object
fstream file;
// open a file with `.open(filename)`
file.open("test.txt");
// check if the file is open
if(!file)
{
cout << "Error opening file" << endl;
return -1;
}
// or use `.is_open()`
if(!file.is_open())
{
cout << "Error opening file" << endl;
return -1;
}
// do something
// close the file
file.close();
}
Read or Write or Read & Write
- To read a file only: use
ifstream
orfstream(filename, ios::in)
- To write a file only: use
ofstream
orfstream(filename, ios::out)
- To read & write a file: use
fstream(filename, ios::in | ios::out)
Note:
ifstream
is used likefstream(filename, ios::in)
but not the sameofstream
is used likefstream(filename, ios::out)
but not the same
Read a file only
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `ifstream(filename)`
ifstream infile("test.txt");
// print the file
while(!infile.eof())
{
// read a line
string line;
getline(infile, line);
// print the line
cout << line << endl;
}
infile.close();
// or use `fstream(filename, ios::in)`
fstream file;
// open a file with `.open(filename)`
file.open("test.txt", ios::in);
// print the file
while(!file.eof())
{
string line;
getline(file, line);
cout << line << endl;
}
// close the file
file.close();
}
Write a file only
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a output file stream object with `ofstream(filename)`
ofstream outfile("test.txt");
// write a line
outfile << "Hello World!" << endl;
// close the file
outfile.close();
// or use `fstream(filename, ios::out)`
fstream file;
// open a file with `.open(filename)`
file.open("test2.txt", ios::out);
// write a line
file << "Hello World!" << endl;
// close the file
file.close();
}
Read & Write a file
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
for( int i = 0; i < 10; i++ )
{
file << "Line " << i << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
for( int i = 0; i < 10; i++ )
{
// read a line
string line;
getline(file, line);
// print the line
cout << line << endl;
}
// close the file
file.close();
}
If file not exist
fstream
, ifstream
and ofstream
will handle the file if it not exist.
- Create new file:
ofstream
,fstream(filename, ios::out)
,fstream(filename, ios::in | ios::out | ios::trunc)
,fstream(filename, ios::out | ios::app)
ios::trunc
&ios::app
will be disscussed later
- Error opening file:
ifstream
,fstream(filename, ios::in)
,fstream(filename, ios::in | ios::out)
Example:
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// open a non-existing file
ifstream infile("test.txt");
// check if the file is open
if(!infile)
{
cout << "Error opening file" << endl;
}
// create a new file and open it
ofstream outfile("test.txt");
// write some text to the file
outfile << "Hello World!" << endl;
outfile.close();
// read the file again
fstream file("test.txt");
// check if the file is open
if(!file)
{
cout << "Error opening file" << endl;
}
// read the file
while (!file.eof())
{
string line;
getline(file, line);
cout << line << endl;
}
// close the file
file.close();
}
Text or Binary
- Text file: save the data in character format
Name,Grade
John,A
Mary,B
- Binary file: save the data with the same format as the computer
00000000: ffd8 ffe1 4812 4578 6966 0000 4d4d 002a ....H.Exif..MM.*
The file saved JPEG header ffd8
, ffe1
, and has 18,450 (0x4812
) bytes of metadata.
The metadata store EXIF information Exif..MM.*
(4578 6966 0000 4d4d 002a
).
Read & Write a text file
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
for( int i = 0; i < 10; i++ )
{
file << "Line " << i << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
for( int i = 0; i < 10; i++ )
{
// read a line
string line;
getline(file, line);
// print the line
cout << line << endl;
}
// close the file
file.close();
}
Result: test.txt
Line 0⏎
Line 1⏎
Line 2⏎
Line 3⏎
Line 4⏎
Line 5⏎
Line 6⏎
Line 7⏎
Line 8⏎
Line 9⏎
<EOF>
Read & Write a binary file
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.bin" first
fstream file("test.bin", ios::in | ios::out | ios::binary);
// write lines
for (int i = 0; i < 10; i++)
{
string temp("Line");
// write string to file, we need to use `.c_str()` to convert string to char*
file.write(temp.c_str(), temp.size());
// for other data type like int, float, double, etc.
// we need to convert the data type to char* first
// use `&` to get the address of the data,
// use `(char *)` to convert the address to char*,
// and use `sizeof(type)` to get the size (number of bytes) of the data type
// then use `.write(data, size)` to write the data to file
file.write((char *)&i, sizeof(int)); // write int value to file
}
file.flush(); // flush the buffer
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
for (int i = 0; i < 10; i++)
{
// read string from file
char temp[5];
// because we store "Line" in the file, so we only need to read 4 bytes
file.read(temp, 4);
// add '\0' to the end of the string
temp[4] = '\0';
// read int from file
int temp_int;
// same as write, we need to convert the data type to char* first
// then use `.read(data, size)` to read the data from file
file.read((char *)&temp_int, sizeof(int));
cout << temp << " " << temp_int << endl;
}
// close the file
file.close();
}
Result: test.bin
00000000: 4c69 6e65 0000 0000 4c69 6e65 0100 0000 Line....Line....
00000010: 4c69 6e65 0200 0000 4c69 6e65 0300 0000 Line....Line....
00000020: 4c69 6e65 0400 0000 4c69 6e65 0500 0000 Line....Line....
00000030: 4c69 6e65 0600 0000 4c69 6e65 0700 0000 Line....Line....
00000040: 4c69 6e65 0800 0000 4c69 6e65 0900 0000 Line....Line....
Append or Overwrite
Two ways to handle a existing file:
- Append (
ios::app
): append the data to the end of the file - Overwrite (
ios::trunc
): overwrite the file
Append (ios::app
)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
for (int i = 0; i < 10; i++)
{
file << "Line " << i << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
for (int i = 0; i < 10; i++)
{
// read a line
string line;
getline(file, line);
// print the line
cout << line << endl;
}
// close the file
file.close();
// open again with `ios::app`
fstream file2("test.txt", ios::in | ios::out | ios::app);
// write a line
for (int i = 10; i < 20; i++)
{
file2 << "Line " << i << endl;
}
// seek to the beginning of the file
file2.seekg(0, ios::beg);
// print the file
for (int i = 0; i < 20; i++)
{
// read a line
string line;
getline(file2, line);
// print the line
cout << line << endl;
}
// close the file
file2.close();
}
Result: test.txt
Line 0⏎
Line 1⏎
Line 2⏎
Line 3⏎
Line 4⏎
Line 5⏎
Line 6⏎
Line 7⏎
Line 8⏎
Line 9⏎
Line 10⏎
Line 11⏎
Line 12⏎
Line 13⏎
Line 14⏎
Line 15⏎
Line 16⏎
Line 17⏎
Line 18⏎
Line 19⏎
<EOF>
Overwrite (ios::trunc
)
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
for (int i = 0; i < 10; i++)
{
file << "Line " << i << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
for (int i = 0; i < 10; i++)
{
// read a line
string line;
getline(file, line);
// print the line
cout << line << endl;
}
// close the file
file.close();
// open again with `ios::app`
fstream file2("test.txt", ios::in | ios::out | ios::trunc);
// write a line
for (int i = 10; i < 20; i++)
{
file2 << "Line " << i << endl;
}
// seek to the beginning of the file
file2.seekg(0, ios::beg);
// print the file
for (int i = 0; i < 20; i++)
{
// read a line
string line;
getline(file2, line);
// print the line
cout << line << endl;
}
// close the file
file2.close();
}
Result: test.txt
Line 10⏎
Line 11⏎
Line 12⏎
Line 13⏎
Line 14⏎
Line 15⏎
Line 16⏎
Line 17⏎
Line 18⏎
Line 19⏎
<EOF>
Sequantial or Random Access
By default, the file is sequantial access.
.tellp()
and .tellg()
can tell the current position of the file.
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
cout << file.tellp() << endl; // print the current position for `<<`
for (int i = 0; i < 10; i++)
{
file << "Line " << i << endl;
cout << file.tellp() << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// print the file
cout << file.tellg() << endl; // print the current position for `>>` and getline()
for (int i = 0; i < 10; i++)
{
// read a line
string line;
getline(file, line);
// print the line
cout << file.tellg() << " " << line << endl;
}
// close the file
file.close();
}
Result: terminal
0
7
14
21
28
35
42
49
56
63
70
0
7 Line 0
14 Line 1
21 Line 2
28 Line 3
35 Line 4
42 Line 5
49 Line 6
56 Line 7
63 Line 8
70 Line 9
Random Access
.seekp(pos)
and .seekg(pos)
can seek to the position of the file.
Three reference position:
ios::beg
: the beginning of the fileios::cur
: the current position of the fileios::end
: the end of the file
// include iostream & fstream for handle the file object
#include <iostream>
#include <fstream>
// short-cut of std::
using namespace std;
int main()
{
// create a input file stream object with `fstream(filename, ios::in | ios::out)`
// Note: create "test.txt" first
fstream file("test.txt", ios::in | ios::out);
// write lines
cout << file.tellp() << endl; // print the current position for `<<`
for (int i = 0; i < 10; i++)
{
file << "Line " << i << endl;
cout << file.tellp() << endl;
}
// seek to the 5th line from the beginning
file.seekp(5 * 7, ios::beg);
cout << file.tellp() << endl; // print the current position for `<<`
for (int i = 15; i < 20; i++)
{
file << "Line " << i << endl;
cout << file.tellp() << endl;
}
// seek to the beginning of the file
file.seekg(0, ios::beg);
// or use `file.seekg(0);`
// print the file
cout << file.tellg() << endl; // print the current position for `>>` and getline()
for (int i = 0; i < 10; i++)
{
// seek to the 3th-previous line if read th 5th line
if (i == 5)
{
file.seekg(-3 * 7, ios::cur);
}
// read a line
string line;
getline(file, line);
// print the line
cout << file.tellg() << " " << line << endl;
}
// close the file
file.close();
}
Result: terminal
0
7
14
21
28
35
42
49
56
63
70
35
43
51
59
67
75
0
7 Line 0
14 Line 1
21 Line 2
28 Line 3
35 Line 4
21 Line 2
28 Line 3
35 Line 4
43 Line 15
51 Line 16
Summary of File I/O 101
- Open & Close File
- constructor or
.open()
- constructor or
- Read or Write or Read & Write
ifstream
andofstream
ios::in
andios::out
inmode
argument offstream
- Text or Binary
ios::binary
inmode
argument
- Append or Overwrite
ios::app
andios::trunc
inmode
argument
- Sequantial or Random Access
.seekp()
and.tellp()
for set/get position of<<
.seekg()
and.tellg()
for set/get position of>>
orgetline()
mode
and file handeling
Ref: std::basic_filebuf<CharT,Traits>::open - cppreference.com
mode | Action if file exists | Action if file does not exist |
---|---|---|
in | Read from start | Error |
out , out\|trunc | Destory contents | Create new |
app , out\|app | Write to end | Create new |
out\|in | Read from start | Error |
out\|in\|trunc | Destory contents | Create new |
out\|in\|app , in\|app | Write to end | Create new |
binray\|in | Read from start | Error |
binray\|out , binray\|out\|trunc | Destory contents | Create new |
binray\|app , binray\|out\|app | Write to end | Create new |
binray\|out\|in | Read from start | Error |
binray\|out\|in\|trunc | Destory contents | Create new |
binray\|out\|in\|app , binray\|in\|app | Write to end | Create new |
Example 1: Big Real Number in Text File [Source]
Ref: Lab 7: 真・大數四則運算 - Introduction to Programming (I)
Example 2: Point & Triangle in Text File (function ver.) [Source]
Example 3: Vector & Matrix in Binary File (function ver.) [Source]
Pratices
- Read & Write Point & Triangle in Binary File
- Read & Write Vector & Matrix in CSV format
- Seprator column by
,
- Seprator row by
\n
- Seprator column by