6 基于文件的流
头文件 <fstream>
c++标准库提供了4个模板类,预定义了4个标准特化版的版本;
1. template class basic_ifstream<>和其特化版ifstream和wifstream,用于读取文件;
2. template class basic_ofstream<>和其特化版iofstream和wofstream,用于将数据写入文件文件;
3. template class basic_fstream<>和其特化版fstream和wfstream,用于读取写入文件;
4. template class basic_filebuf<>和其特化版filebuf和wfilebuf,用于其他几种文件流类进行实际的字符读写工作;
1.文件标志及其使用
- 文件描述符是代表文件的标志;每个流附着在一个开启的io通道上面,文件描述符可以将文件流初始化。
- 文件描述符是一个整数,用于辨识开始的io通道。
通常c++系统预定义的3个文件描述符:
(1).0 代表标准输入通道;
(2). 1代表标准输出通道;
(3). 2代表标准错误信息通道。
这些通道连接文件,控制台,其他进制或者io设备。
1.1 文件简介
为了控制文件处理模式,类ios_base定义了一组标志,器型别为openmode,
1.1.1 ios_base类的标志
标志 | 含义 |
---|---|
in | 打开,用于读写(ifstream的默认模式) |
out | 打开,用于改写(ostream的默认模式) |
app | 写入时始终添加与尾端 |
ate | 打开文件后,令读写位置移到文件尾端 |
trunc | 将先前的文件移除 |
binary | 不要替换特殊字符 |
说明:
1. binary能够使得stream封锁特殊字符或字符序列的转换。
2. 当文件是二进制的时候,需要使用标志binary,当复制文件的时候,将源文件字符逐一读出,不要做任何修改写入目标文件,
3. 如果文件是文本类型,不需要使用binary,此时处理换行符号,则改为两个字符。
4. 多个标志可以使用|
将标志组合起来
1.1.2 常见的c++标志组合
ios_base标志 | 意义 | c模式 |
---|---|---|
in | 读取文件(文件必须存在) | “r ” |
out | 清空之后改写(有必要才产生) | “w” |
out|trunc | 清空之后改写(有必要才产生) | “w” |
out|app | 添加 (有必要才产生) | “a” |
in|out | 读和写,最初位置在起始点(文件必须存在) | “r+” |
in|out|trunc | 先清空,在读写(有必要才产生) | “w+” |
说明:
1. 文件的真正执行打开文件操作的是stream buffer classes.
2. 文件的实际操作是stream classes实现
file stream拥有的文件可以显式的开和关闭;
stl定义的3个成员函数:
open(name);
open(name,flags)
close()
isopen()
1.2 简单的文件I/O
使用程序实现 文件的写入:
(1). 创建一个ofstream对象,管理输出流;
(2). 该对象与特定的文件需要进行关联;
(3). 使用cout的方式使用此对象,区别在于: 输出将进入文件,而不是屏幕。
使用程序实现文件的读取:
(1). 创建一个ifstream对象,管理输入流;
(2). 该对象与特定的文件需要进行关联;
(3). 使用cin的方式使用此对象.
说明:
- 当输入流和输出流对象过期的时候,流到文件的连接自动关闭
- 也可使用close()显式的进行关闭
- 但调用close()并不会真正的删除流,仅仅断开两者的连接,流仍然存在,流的缓冲区也存在,并且该流还可以重新连接或者连接到其他文件。
1.3 打开文件和文件模式
ifstream和ofstream各自定义了open()和is_open()实现文件的打开和是否打开的判断;
1.3.1 ifstream
函数原型:
open():
void open (const char* filename, ios_base::openmode mode = ios_base::in);
void open (const string& filename, ios_base::openmode mode = ios_base::in);
is_open():
bool is_open() const;
1.3.2 ofstream
函数原型:
open():
void open (const char* filename, ios_base::openmode mode = ios_base::out);
void open (const string& filename, ios_base::openmode mode = ios_base::out);
is_open():
bool is_open() const;
说明:
1.ifstream和ofstream的open()第二个参数定义了打开的模式;定义的模式可以参考前面的表格;
1.3.3 追加文件模式
ofstream fout;
fout.open("test.txt",ios_base::out | ios_base::app);
1.3.4 二进制文件
std::ios::binary : 打开模式指定文件打开为二进制文件,而不是文本文件。
- unix系统中,文件文件和二进制文件无区别
- windows中,std::ios::binary是有意义的;
文本文件和二进制文件的转换:
在程序向二进制文件写入新行符“\n”的时候,文件系统将写入单个新行符。多数平台上,新行符与换行符(0x0a)相同;
程序向文本文件写入新行符,文件系统写入两个字符: 回车符(0x0d)和换行符(0x0a);
程序中二进制文件读取一个新行符的时候,文件系统把单个字符读取到存储区中;
程序从文本文件中读取一对回车/换行符的时候,文件系统把一对字符转换成存储区中的一个新行符;
在程序从文本文件中读取一个新行符的时候,换行符前没有回车符,文件系统把一个新行符插入到存储区;
总结:
1. 上述方法涉及到新行符表示的转换
2. 还有文件位置的操作
3.二进制文件格式,可以实现整块的写入和读取数据;