1、文件操作类
fstream: 可同时读写操作的文件类(由iostream引申而来)
ofstream: 写操作(输出)的文件类(由ostream引申而来)
ifstream: 读文件(输入)的文件类(由istream引申而来)
(文件类的实质,解释的很好)
对这些类的一个对象所做的第一个操作通常就是将它和一个真正的文件联系起来,也就是说打开一个文件。被打开的文件在程序中由一个流对象(stream object)来表示(这些类的实例),而这个流对象所做的任何输入输出操作实际上就是对该文件所做的操作。
2、打开文件:
(1)使用流对象的open()函数打开文件,默认以写方式打开文件时,文件不存在则创建,而以读打开时不存在则打开不成功。文件打开时默认是以兼容共享模式。如:
void open (const char * filename, openmode mode);mode是以下标志符的一个组合:
文件打开方式选项 | |
ios::in = 0x01 | 为输入(读)而打开文件 |
ios::out = 0x02 | 为输出(而)而打开文件 |
ios::ate = 0x04 | 初始位置:文件尾,但是以输出方式打开时,也是存在文件则先删除。 |
ios::app = 0x08 | 所有输出附加在文件末尾,即使定位指针也是附加在文件末尾。 |
ios::trunc = 0x10 | 如果文件已存在则先删除该文件 |
ios::binar = 0x80 | 二进制方式 |
文件保护方式选项 | 用在缓存文件中 |
filebuf::openprot | 默认的兼容共享方式 |
filebuf::sh_none | 独占,不共享 |
filebuf::sh_read | 读共享 |
filebuf::sh_write | 写共享 |
这些标志符可以被组合使用,中间以“或”操作符“|”间隔。例如,我们想以二进制方式打开文件“example.bin”来写入一些数据,我们可以通过以下方式调用成员函数open()来实现
ofstream file;
file.open("example.bin", ios::out | ios::app | ios::binary);
ofstream, ifstream和fstream所有这些类的成员函数open都包含了一个默认打开文件的方式,这三个类的默认方式各不相同:
类 | 参数的默认方式 |
fstream | ios::in | ios::out |
ifstream | ios::in |
ofstream | ios::out | ios::trunc |
只有当函数被调用而没有声明mode的情况下,默认值才会被采用。如果函数调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。(自己应该养成声明mode的习惯)
(2)构造函数打开文件
对上面打开文件example.bin文件的方式改写
ofstream file ("example.bin", ios::out | ios::app | ios::binary);
两种打开文件的方式都是正确的。
(3)检测打开是否成功
使用“is_open()”成员函数来检测是否顺利打开,它返回一个bool值,“true”代表顺利打开,“false”代表打开失败。
3、关闭文件
当文件读写完成之后,必须将文件关闭以使其重新变为可访问的。关闭文件需要调用“close()”函数,它负责将缓存中数据释放出来并关闭文件。
这个函数一旦调用,原先的流对象就可以被用来打开其他的文件了,打开其他文件时,一定要先用clear()函数来将流对象的指针等标志位数据重新初始化。
如果文件不存在时,这时候不止调用open会出错,调用close也会出错。
为了防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close()。
4、读写文件
(1)文本文件(Text mode files)
类ofstream, ifstream和fstream分别从ostream,istream和iostream中引申而来,这就是为什么fstream的对象可以使用其父类的成员来访问数据。
我们使用重载的“<<”和“>>”来“输入”和“输出”,如
// writing on a text file file example.txt
#include <fiostream.h>
int main () {
ofstream examplefile ("example.txt");
if (examplefile.is_open()) {
examplefile << "This is a line.\n"; // 写入文件时,如果定位了指针,默认是覆盖已有的文件内容,
// 而不会将已有的内容后移。
examplefile << "This is another line.\n";
examplefile.close();
}
return 0;
}
(2)二进制文件
5、检测EOF
成员函数eof()用来检测是否到达文件尾:
到达文件尾 | 返回非0值 |
未到达文件尾 | 返回0 |
6、获取和设置流指针(get and put stream pointers)
所有的输入/输出流对象都至少有一个流指针:
ifstream | get pointer,指向下一个将被读取的元素 |
ofstream | put pointer,指向下一个将写入的位置 |
fstream | 同时继承get和put |
我们可以使用以下成员函数来读出和配置这些指向流中读写位置的流指针:
streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值
ifstream | |
tellg() | 返回pos_type类型的值,根据(ANSI-C++标准),是一个整数,代表当前的指针位置 |
seekg ( off_type offset, seekdir direction ) | 根据direction的初始位置移动offset个位置 |
ofstream | |
tellp() | 同tellg() |
seekp ( off_type offset, seekdir direction ); | 同seekg |
direction的值可以是以下三种中的一个:
ios::beg | 从流开始的位置 |
ios::cur | 从流指针当前的位置 |
ios::end | 从流末尾的位置 |
由于文本文件中某些特殊字符可能被修改,所有这些函数一般用于二进制文件中。