17-简单的文件IO
17.4.1 简单的文件I/O
要让程序写入文件,必须这样做:
1.创建一个ofstream对象来管理输出流;
2.将该对象与特定的文件关联起来;
3.以使用cout的方式使用该对象,唯一的区别是输出将进入文件,而不是屏幕。
要完成上述任务,首先应包含头文件fstream。对于大多数(但不是全部)实现来说,包含该文件便自动包括iostream文件,因此不必显示包含iostream。然后声明一个ofstream对象:
ofstream fout; // create an ofstream object named fout
对象名可以是任意有效的C++名称,如fout、outFile、cgate或didi。
接下来,必须将这个对象与特定的文件关联起来。为此,可以使用open()方法。例如,假设要打开文件jar.txt进行输出,则可以这样做:
fout.open("jar.txt"); // associate fout with jar.txt
可以使用另一个构造函数将这两步(创建对象和关联到文件)合并成一条语句:
ofstream fout("jar.txt"); // create fout object, associate it with jar.txt
然后,以使用cout的方式使用fout(或选择的其他名称)。例如,要将Dull Data放到文件中,可以这样做:
fout << "Dull Data";
由于ostream是ofstream类的基类,因此可以使用所有的ostream方法,包括各种插入运算符定义、格式化方法和控制符。ofstream类使用被缓冲的输出,因此程序在创建像fout这样的ofstream对象时,将为输出缓冲区分配空间。如果创建了两个ofstream对象,程序将创建两个缓冲区,每个对象各一个。像fout这样的ofstream对象从程序那里逐字节地收集输出,当缓冲区填满后,它便将缓冲区内容一同传输给目标文件。由于磁盘驱动器被设计称以大块的方式传输数据,而不是逐字节地传输,因此通过缓冲可以大大提高从程序到文件传输数据的速度。
以这种方式打开文件来进行输出时,如果没有这样的文件,将创建一个新文件;如果有这样的文件,则打开文件将清空文件,输出将进入到一个空文件中。本章后面将介绍如何打开已有的文件,并保留其内容。
警告: 以默认模式打开文件进行输出将自动把文件的长度截短为零,这相当于删除已有的内容。
读取文件的要求与写入文件相似:
创建一个ifstream对象来管理输入流;
将该对象与特定的文件关联起来;
以使用cin的方式使用该对象。
上述读文件的步骤类似于写文件。首先,当然要包含头文件fstream。然后声明一个ifstream对象,将它与文件名关联起来。可以使用一两条语句来完成这项工作:
// two statements
ifstream fin; // create ifstream object called fin
fin.open("jellyjar.txt"); // open jellyjar.txt for reading
// one statement
ifstream fis("jamjar.txt"); // create fis and associate with jamjar.txt
现在,可以像使用cin那样使用fin或fis。例如,可以这样做:
char ch;
fin >> ch; // read a character from the jellyjar.txt file
char buf[80];
fin >> buf; // read a word from the file
fin.getline(buf, 80); // read a line from the file
string line;
getline(fin, line); // read from a file to a string object
输入和输出一样,也是被缓冲的,因此创建ifstream对象与fin一样,将创建一个由fin对象管理的输入缓冲区。与输出一样,通过缓冲,传输数据的速度比逐字节传输要快得多。
当输入和输出流对象过期(如程序终止)时,到文件的连接将自动关闭。另外,也可以使用close()方法来显式地关闭到文件的连接:
fout.close(); // close output connection to file
fin.close(); // close input connection to file
关闭这样的连接并不会删除流,而只是断开流到文件的连接。然而,流管理装置仍被保留。例如,fin对象与它管理的输入缓冲区仍然存在。您稍后将知道,可以将流重新连接到同一个文件或另一个文件。
我们来看一个简短的例子。程序清单17.16的程序要求输入文件名,然后创建一个名称为输入名的文件,将一些信息写入到该文件中,然后关闭该文件。关闭文件将刷新缓冲区,从而确保文件被更新。然后,程序打开该文件,读取并显示其内容。注意,该程序以使用cin和cout的方式使用fin和fout。另外,该程序将文件名读取到一个string对象中,然后使用方法c_str()来给ofstream和ifstream的构造函数提供一个C-风格字符串参数。
程序清单17.16 fileio.cpp
// fileio.cpp -- saving to a file
#include <iostream> // not needed for many systems
#include <fstream>
#include <string>
int main()
{
using namespace std;
string filename;
cout << "Enter name for new file: ";
cin >> filename;
// create output stream object for new file and call it fout
ofstream fout(filename.c_str());
fout << "For your eyes only!\n"; // write to file
cout << "Enter your secret number: "; // write to screen
float secret;
cin >> secret;
fout << "Your secret number is " << secret << endl;
fout.close(); // close file
// create input stream object for new file and call it fin
ifstream fin(filename.c_str());
cout << "Here are the contents of " << filename << ":\n";
char ch;
while (fin.get(ch)) // read character from file and
cout << ch; // write it to screen
cout << "Done\n";
fin.close();
return 0;
}
下面是程序清单17.16中程序的运行情况:
Enter name for new file: pythag
Enter your secret number: 3.14159
Here are the contents of pythag:
For your eyes only!
Your secret number is 3.14159
Done
如果查看该程序所在的目录,将看到一个名为pythag的文件,使用文本编辑器打开该文件,其内容将与程序输出相同。