一、文件的概念
对于用户来说,常用到的文件有两大类:程序文件和数据文件。而根据文件中数据的组织方式,则可以将文件分为ASCII 文件和二进制文件。
- ASCII 文件,又称字符文件或者文本文件,它的每一个字节放一个 ASCII 代码,代表一个字符。
- 二进制文件,又称内部格式文件或字节文件,是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。
数字 64 在内存中表示为 0100 0000,若将其保存为 ASCII 文件,则要分别存放十位 6 和个位 4 的 ASCII 码,为 0011 0110 0011 0100,占用两个字节;若将其保存为二进制文件,则按内存中形式直接输出,为 0100 0000,占用一个字节。
ASCII 文件中数据与字符一一对应,一个字节代表一个字符,可以直接在屏幕上显示或打印出来,这种方式使用方便,比较直观,便于阅读,但一般占用存储空间较大,而且输出时要将二进制转化为 ASCII 码比较花费时间。
二进制文件,输出时不需要进行转化,直接将内存中的形式输出到文件中,占用存储空间较小,但一个字节并不对应一个文件,不能直观显示文件中的内容。
二、文件流和文件流对象
2.1 文件流
文件流是以外存文件未输入输出对象的数据流。输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据。每一个文件流都有一个内存缓冲区与之对应。
C++ 中有三个用于文件操作的文件类:
- ifstream 类,它是从 istream 类派生来的,用于支持从磁盘文件的输入。
- ofstream 类,它是从 ostream 类派生来的,用于支持向磁盘文件的输出。
- fstream 类,它是从 iostream 类派生来的,用于支持对磁盘文件的输入输出。
要以磁盘文件为对象进行输入输出,必须定义一个文件流类的对象,通过文件流对象将数据从内存输出到磁盘文件,或者将磁盘文件输入到内存。
2.2 文件流对象
定义文件流对象后,我们还需要将文件流对象和指定的磁盘文件建立关联,以便使文件流流向指定的磁盘文件,并确定文件的工作方式(输入还是输出,二进制还是 ASCII)。我们可以在定义流对象的时候指定参数来调用构造函数,或者通过成员函数 open 来进行文件流对象和指定文件的关联。
2.3 文件模式
每个流都有一个关联的文件模式(file mode),用来指出如何使用文件。
文件模式 | 模式含义 |
---|---|
ios::in | 以读方式打开 |
ios::out | 以写方式打开(从文件头开始写入,但不会删除旧内容) |
ios::app | 每次写操作前均定位到文件末尾(append) |
ios::ate | 打开文件后立即定位到文件末尾 |
ios::trunc | 截断文件,表示打开文件时,旧的内容将立即删除 |
ios::binary | 以二进制方式进行IO |
三、对 ASCII 文件的操作
然后,我们就可以用类似 cin 或者 cout 的方式将数据读出或写入文件,只不过是输入输出的对象变成了文件而已。当然,在对磁盘文件完成读写操作后,我们可以通过 close 方法来解除磁盘文件和文件流对象的关联。
1 |
|
也可以利用文件流对象的成员函数 get, put 等,其用法就和标准输入输出介绍的一样。
1 | int main() |
四、对二进制文件的操作
二进制文件的操作需要在打开文件的时候指定打开方式为 ios::binary,并且还可以指定为既能输入又能输出的文件,我们通过成员函数 read 和 write 来读写二进制文件。
istream& read (char* s, streamsize n);
ostream& write (const char* s, streamsize n);
1 |
|
在磁盘文件中有一个文件指针,用来指明当前读写的位置。每次写入或者读出一个字节,指针就向后移动一个字节。对于二进制文件,允许对指针进行控制,使它移动到所需的位置,以便在该位置上进行读写。
ostream& seekp (streampos pos);
将输出文件中指针移动到指定的位置ostream& seekp (streamoff off, ios_base::seekdir way);
以参照位置为基准对输出文件中的指针移动若干字节streampos tellp();
返回输出文件指针当前的位置istream& seekg (streampos pos);
将输入文件中指针移动到指定的位置istream& seekg (streamoff off, ios_base::seekdir way);
以参照位置为基准对输入文件中的指针移动若干字节streampos tellg();
返回输入文件指针当前的位置
其中,参照位置有以下几个选择:
ios_base::beg
文件开始位置ios_base::cur
文件当前位置ios_base::end
文件末尾位置
参考文章: