为了在C++中执行文件IO,我们使用了ofstream、ifstream和fstream类。
- ofstream:要在文件上写入的流类
- ifstream:要从文件中读取的流类
- fstream:从文件读取和向文件写入的流类
将文件与流对象关联的过程称为"打开文件"。打开文件时,我们可以指定打开文件的模式。我的查询与ios::out
和ios:in
模式有关。
当我创建一个ofstream
对象并以ios::in
模式打开文件时,我能够写入文件,但仅当文件已创建时(使用ios::out
模式时,如果文件不存在,也会创建文件)
但是,当我创建ifstream
对象并以ios::out
模式打开文件时,我可以读取该文件。
我的问题是,当流的类型(ifstream
/ofstream
)本身指定要执行哪种类型的操作(输入/输出)时,为什么语言提供这些模式(ios::in
/ios::out
)?
同样,为什么这种不明确的用法(ofstream
与ios::in
和ifstream
与ios::out
)在一种情况下有效,而在另一种情况中失败(尽管仅当文件不存在时)?
ofstream
、ifstream
和fstream
类是底层filebuf
的高级接口,可以通过流的rdbuf()
成员函数访问。
当您使用某种模式mode
打开ofstream
时,它会使用mode | ios_base::out
打开底层流缓冲区。类似地,ifstream
使用mode | ios_base::in
。CCD_ 26将CCD_。
上面的意思是,以下代码打开的文件具有完全相同的打开标志:
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()
执行完全相同的操作,并且这三个操作就像您使用C调用fopen("a.txt", "r+")
打开文件一样,CCD_31为您提供读/写访问权限,不会截断文件,如果文件不存在,则会失败。
那么,为什么我们有三个不同的班呢?如前所述,这些是在较低级别流缓冲区上提供高级接口的高级类。其思想是ifstream
具有用于输入的成员函数(如read()
),ofstream
具有用于输出的成员函数,而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
因为模式不限于输入/输出。例如,ifstream
的构造函数看起来像:
explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );
请注意,默认值是ios_base::in
,因此您不必自己指定它。然而,mode
设置的流标志不限于in
/out
,而是包括:
app
(append)在每次输出操作之前,将流的位置指示器设置到流的末尾ate
(在末尾)打开时将流的位置指示器设置为流的末尾binary
(二进制)将流视为二进制而非文本in
(input)允许对流进行输入操作out
(输出)允许对流进行输出操作trunc
(截断)任何当前内容都将被丢弃,假设打开时长度为零