C++打开文件的两种方式(文件流类和open函数)
在C++中,操作(读、写)文件之前必须先打开文件,打开方式有两种,一种是利用文件流类的构造函数,另一种是调用文件流类提供的 open() 成员函数,两种打开方式在效果上是相同的。
所有的文件流类都至少提供了两个版本的构造函数,一个不带参数的默认构造函数和一个带参数的构造函数,参数用于指定目标文件以及打开文件的模式,如下所示:
举个简单的例子:
各个文件流的 open() 函数如下:
举个简单的例子:
第 18 行的
使用文件流的 open() 函数打开文件时有一点需要注意,如果该文件流已经打开了一个文件,那么在打开新文件之前,必须关闭当前文件,否则 open() 函数调用会失败。
文件流类打开文件
C++文件流类提供了更高级的、面向对象的文件操作接口,其中 ifstream 用于读取文件,ofstream 用于写入文件,而 fstream 则可用于读写文件。所有的文件流类都至少提供了两个版本的构造函数,一个不带参数的默认构造函数和一个带参数的构造函数,参数用于指定目标文件以及打开文件的模式,如下所示:
//ifstream 类的构造函数 ifstream(); explicit ifstream (const char* filename, ios_base::openmode mode = ios_base::in); //ofstream 类的构造函数 ofstream(); explicit ofstream (const char* filename, ios_base::openmode mode = ios_base::out); //fstream 类的构造函数 fstream(); explicit fstream (const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);其中带参数的构造函数可以直接打开目标文件:
- filename:指定要打开的目标文件。
- mode:指定打开文件的模式,如表 1 所示。
模式标记 | 适用对象 | 作用 |
---|---|---|
ios::in |
ifstream fstream |
打开文件用于读取数据。如果文件不存在,则打开出错。 |
ios::out |
ofstream fstream |
打开文件用于写入数据。如果文件不存在,则新建该文件;如果文件原来就存在,则打开时清除原来的内容。 |
ios::app |
ofstream fstream |
打开文件,用于在其尾部添加数据。如果文件不存在,则新建该文件。 |
ios::ate | ifstream | 打开一个已有的文件,并将文件读指针指向文件末尾(读写指 的概念后面解释)。如果文件不存在,则打开出错。 |
ios:: trunc | ofstream | 打开文件时会清空内部存储的所有数据,单独使用时与 ios::out 相同。 |
ios::binary |
ifstream ofstream fstream |
以二进制方式打开文件。若不指定此模式,则以文本模式打开。 |
ios::in | ios::out | fstream | 打开已存在的文件,既可读取其内容,也可向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。 |
ios::in | ios::out | ofstream | 打开已存在的文件,可以向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。 |
ios::in | ios::out | ios::trunc | fstream | 打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。 |
举个简单的例子:
#include <iostream> #include <fstream> using namespace std; int main() { ifstream inFile("c:\\tmp\\test.txt", ios::in); if (inFile) inFile.close(); else cout << "test.txt doesn't exist" << endl; ofstream oFile("test1.txt", ios::out); if (!oFile) cout << "error 1"; else oFile.close(); fstream oFile2("tmp\\test2.txt", ios::out | ios::in); if (!oFile2) cout << "error 2"; else oFile.close(); return 0; }对于打开的文件,当不再进行任何操作时,要手动调用 close() 成员函数关闭文件。
open()函数打开文件
使用不带参数的构造函数,意味着该文件流对象的目标文件还没有确定。在后面的程序中,可以调用文件流类提供的 open() 成员函数打开指定的文件。各个文件流的 open() 函数如下:
//std::ifstream::open void open (const char* filename, ios_base::openmode mode = ios_base::in); //std::ofstream::open void open (const char* filename, ios_base::openmode mode = ios_base::out); //std::fstream::open void open (const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);和文件流类的构造函数相比不难看出,open() 成员函数和带参数的构造函数非常相似,其目的也很相似,都是以指定的模式打开指定的文件。
举个简单的例子:
#include <iostream> #include <fstream> using namespace std; int main() { ifstream inFile; inFile.open("c:\\tmp\\test.txt", ios::in); if (inFile) //条件成立,则说明文件打开成功 inFile.close(); else cout << "test.txt doesn't exist" << endl; ofstream oFile; oFile.open("test1.txt", ios::out); if (!oFile) //条件成立,则说明文件打开出错 cout << "error 1" << endl; else oFile.close(); oFile.open("tmp\\test2.txt", ios::out | ios::in); if (oFile) //条件成立,则说明文件打开成功 oFile.close(); else cout << "error 2" << endl; fstream ioFile; ioFile.open("..\\test3.txt", ios::out | ios::in | ios::trunc); if (!ioFile) cout << "error 3" << endl; else ioFile.close(); return 0; }调用 open() 成员函数时,给出的文件名可以是全路径的,如第 7 行的
c:\\tmp\\test.txt
, 指明文件在 c 盘的 tmp 文件夹中;也可以只给出文件名,如第 13 行的test1.txt
,这种情况下程序会在当前文件夹(也就是可执行程序所在的文件夹)中寻找要打开的文件。第 18 行的
tmp\\test2.txt
给出的是相对路径,说明 test2.txt 位于当前文件夹的 tmp 子文件夹中。第 24 行的..\\test3.txt
也是相对路径,代表上一层文件夹,此时要到当前文件夹的上一层文件夹中查找 test3.txt。此外,..\\..\\test4.txt
、..\\tmp\\test4.txt
等都是合法的带相对路径的文件名。使用文件流的 open() 函数打开文件时有一点需要注意,如果该文件流已经打开了一个文件,那么在打开新文件之前,必须关闭当前文件,否则 open() 函数调用会失败。