为了在 C++ 中执行文件 IO,我们使用了 ofstream、ifstream 和 fstream 类。
- ofstream:写入文件的流类
- ifstream:从文件中读取的流类
- fstream: 读写文件的流类
将文件与流对象关联的过程称为“打开文件”。
打开文件时,我们可以指定打开文件的模式。
我的查询与 ios::out
和 ios:in
模式有关。
当我创建一个 ofstream
对象并以 ios::in
模式打开文件时,我能够
写入文件,但前提是它已经创建(使用 ios::out
模式文件,如果它不存在,也会创建它)。
但是当我创建 ifstream
对象并使用 ios::out
模式打开文件时,我可以从文件中读取。
我的问题是为什么当流的类型(ifstream
/ofstream
) 本身指定正在执行哪种类型的操作(输入/输出)?
还有为什么这种模棱两可的用法(ofstream
与 ios::in
和 ifstream
与 ios::out
) 在一种情况下有效并且在另一种情况下失败(尽管仅当文件不存在时)?
最佳答案
ofstream
、ifstream
和 fstream
类是底层 filebuf
的高级接口(interface),可以通过流的rdbuf()
成员函数访问。
当您以某种模式 mode
打开 ofstream
时,它会以 mode | 打开底层流缓冲区。 ios_base::out
。类似地 ifstream
使用 mode | ios_base::in
。 fstream
将 mode
参数逐字传递到底层流缓冲区。
上面的意思是下面的代码用完全相同的打开标志打开文件:
fstream f("a.txt", ios_base::in | ios_base::out);
ifstream g("a.txt", ios_base::out);
ofstream h("a.txt", ios_base::in);
在这些行之后,您可以使用 f.rdbuf()
、g.rdbuf()
和 h.rdbuf()
执行完全相同的操作code>,所有这三个行为就像您使用 C 调用打开文件一样文件,如果文件不存在则失败。
那么,为什么我们有三个不同的类?如前所述,这些是在较低级别的流缓冲区上提供高级接口(interface)的高级类。这个想法是 ifstream
具有用于输入的成员函数(如 read()
),ofstream
具有用于输出的成员函数(如 write ()
) 而 fstream
两者都有。例如你不能这样做:
g.write("abc", 3); // error: g does not have a write function
但这行得通,因为虽然 g
是一个 ifstream
,但我们用 ios_base::out
:
g.rdbuf()->sputn("abc", 3); // we still have write access
关于C++文件流打开模式歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12365218/