基本技能11.11:随机访问文件
到目前为止,我们一直都是按照顺序的方式来读取文件。实际上我们是可以以随机的方式来对文件进行访问的。在C++的输入/输出系统中,我们可以使用seekg()和seekp()函数来随机访问文件。他们最常用的形式如下:
istream &seekg(off_type offset, seekdir origin);
ostream &seekp(off_type offset, seekdir origin);
其中:off_type是由ios定义的整形类型。它的取值范围足以用于表示有效的偏移量。seekdir是一个可以取下列值得枚举类型:
值 |
含义 |
ios::beg |
文件的开始 |
ios::cur |
当前位置 |
ios::end |
文件的末尾 |
C++的输入/输出系统了管理了两个和文件相关联的指针。一个就是读取文件的指针,它表明了下一次读取的位置;还有一个就是写入文件的指针,它指示了下一次写入操作的位置。每进行一次输入或者输出操作,相应的指针就会自动的向前进行移动。通过使用seekg()和seekp()这两个函数,我们就可以移动这两个指针,实现对文件的随即访问。
函数seekg()把相关联的文件的读取指针从指定的起点移动offset个字节;seekp()函数把相关文件的写入指针从指定的起点移动offset个字节。
通常来说,随即访问进行输入输出仅用于二进制文件的操作。这是因为文本文件读取时的字符转换有可能导致指针的位置和文件实际内容中的位置不能正确对应。
下面的程序就演示了函数seekp()的用法。程序运行时需要我们在命令行输入文件的名称以及我们期望的文件被修改的位置,程序将在这个位置写入一个X字符。请注意其中的文件必须是以读写的方式打开。
//文件的随机访问 #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int main(int argc, char * argv[]) { if(argc != 3) { cout << "Usage: CHANGE<filename> <byte> \n"; return 1; } fstream out(argv[1], ios::in | ios::out | ios::binary); if ( !out ) { cout << "Cannot ope file.\n"; return 1; } out.seekp(atoi(argv[2]), ios::beg); out.put('X'); out.close(); return 0; }
接下来的程序中使用到了seekg()函数。程序显示从用户指定的位置开始到文件结束的内容。
//从指定的位置开始显示文件的内容 #include <iostream> #include <fstream> #include <cstdlib> using namespace std; int main(int argc, char * argv[]) { char ch; if ( argc != 3) { cout << "Usage : NAME <file name> <starting location>\n"; return 1; } ifstream in(argv[1], ios::in|ios::binary); if (!in) { cout << "Cannot open file.\n"; return 1; } in.seekg(atoi(argv[2]),ios::beg); while(in.get(ch)) { cout << ch; } return 0; }
我们还可以通过下面的两个函数来获取两个指针的当前位置:
pos_type tellg();
pos_type tellp();
其中的pos_type是有ios定义的能够涵盖上述两个函数中任意一个返回值的最大值的类型。seekg()和seekp()函数还有如下的重载形式:
istream & seekg(pos_type positon);
ostream &seekp(pos_type position);
可以把文件指针移动到指定的位置。
练习
1. 那个函数可以用来判断是否遇到了文件结束?
2. getline()函数是用来做什么的?
3. 那些函数可用于对文件进行随机的访问?