一、关键点
头文件 fstream 定义了三个类型来支持文件IO:ifstream、ofstream、fstream
其实上面三个类型就是类,这些类为了管理与流关联的文件,而定义了好多相关的操作:
操作 | 说明 | 示例 |
(i/o)fstream io | 创建一个未绑定的文件流io | ifstream in; |
(i/o)fstream io(file) | 基于上面的基础,打开名为file的文件,将文件流io与file绑定起来 | ifstream input("data.txt"); |
(i/o)fstream io(file, mode) | 基于上面的基础,但按指定的mode打开文件 | ofstream out("data.txt", ofstream::app) |
io.open(file) | 打开名为file的文件,并将文件与io绑定 | string s(data.txt); in.open(s); |
io.close() | 关闭与io绑定的文件 | in.close(); |
io.is_open() | 判断与io关联的文件是否成功打开并且尚未关闭 | 略 |
接受一个 iostream 类型引用(或指针)参数的函数,可以用一个对应的fstream(或sstream)类型来调用(继承类的对象可以替代基类的对象)。
二、相关操作
1. 创建文件流对象
- ifstream in; //构造一个输入文件流in,但并未关联到任何文件(即空文件流对象)
- ifstream in(ifile); //构造一个 ifstream 对象并打开给定文件
- ofstream out; //输出文件流未与任何文件相关联
2. 可以调用open将空文件流对象与文件关联起来
- ofstream out;
- out.open(ifile + ".copy"); //打开指定文件
注:如果构造文件流时就提供了文件名,那么open会自动被调用
3. 检查open是否成功
如果调用 open 失败,failbit 会被置位(即一个IO操作失败的意思):
- if (out) //如果open失败,条件会为假
4. 对一个已经打开的文件流调用open
一个文件流已经打开,它就保持与对应文件的关联,故“对一个已经打开的文件流调用open”会失败,并会导致failbit 被置位。
如果我们要将文件流关联到另外一个文件,必须首先关闭已经关联的文件,关闭后,才可以关联新的文件。
- in.close(); //关闭文件
- in.open(ifile + "2"); //打开另一个文件
5. 自动析构
当构造的文件流是局部对象时,它离开其作用域时(即fstream对象被销毁),与之关联的文件会自动关闭(即close会自动被调用)。
三、文件模式
每个流都有一个关联的文件模式(file mode),用来指出如何使用文件。
文件模式 | 说明 |
in | 以读方式打开 |
out | 以写方式打开 |
trunc | 截断文件 |
app | 每次写操作前均定位到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
binary | 以二进制方式进行IO |
无论用open方式或初始化流方式来打开文件,我们都可以指定文件模式。
1. 指定文件模式的限制
即使我们没有指定trunc,以out模式打开的文件也会被截断(即文件内容没了),为了保留以out 模式打开的文件的内容,我们必须同时指定app模式(也可以是in模式)
只要trunc没被设定,就可以设定app模式(在此模式下,即使没有指定out,文件也以输出方式被打开)
2. 默认文件模式
与输入文件流关联的文件默认以 in 模式打开
与输出文件流关联的文件默认以out模式打开(附带截断)
与fstream关联的文件默认以in和out模式打开
3. 以out 模式打开文件会丢弃已有数据
【file1会被截断】
ofstream out("file1");
ofstream out("file1", ofstream::out);
ofstream out("file1", ofstream::out | ofstream::trunc);
【保留文件内容】
ofstream out("file1", ofstream::app);
ofstream out("file1", ofstream::out | ofstream::app);
out.open("file1", ofstream::app);
四、例题