文件的随机读写
在C语言中要实现文件的随机读写是依靠文件位置指针,在C++中实现文件的随机读写也是依靠移动文件位置指针来完成的。
C++在文件输入流和文件输出流中都提供了设置文件位置指针的函数,对于输入流,istream类提供了seekg()、tellg()两个函数,其函数声明如下所示:
istream& seekg(streampos); //文件指针直接定位
istream& seekg(streamoff, ios::seek_dir); //指针相对定位
long tellg(); //返回指针的当前位置
接下来对上述三个函数进行详细讲解:
1、seekg(streampos)函数
seekg(streampos)函数用于直接定位文件位置指针,streampos是长整型数据,它是以文件开始处为参考点,将文件位置指针移动到参数所指位置。
2、seekg(streamoff, ios::seek_dir)函数
两个参数的seekg()函数是相对定位文件位置指针,streamoff也是长整型数据,表示指针的偏移量,可正可负可零,为正时表示指针向后移动,为负时表示指针向前移动,为零时表示指针相对于当前位置不动。seek_dir是ios类中定义的一个公有枚举类型,其定义如下所示:
enum seek_dir
{
ios::beg = 0; //文件开头
ios::cur = 1; //文件指针当前位置
ios::end = 2; //文件结尾
}
seek_dir取不同的值表示从不同的位置开始移动指针。例如下面的代码:
ifs.seekg(20L, ios::cur);
ifs.seekg(-20L, ios::end);
第一个语句表示将文件位置指针从当前位置向后移动20个字节;第二个语句表示将文件位置指针从文件尾向前移动20个字节。
3、tellg()函数
tellg()函数~~tellg()~~是返回指针的当前位置,它往往与seekg()函数配合使用。
另外,对于输出流,ostream类也提供了个两个函数:seekp()、tellp(),其函数声明如下所示:
ostream& seekp(streampos);
ostream& seekp(streamoff, ios::seek_dir);
long tellp();
这一组函数的功能与输入流指针控制函数的功能完全相同。两组函数名中字母’g’是get的缩写,字母’p’是put的缩写。
为了读者更好的掌握这两组函数的使用,接下来我们通过一个案例来随机读写一个二进制文件。
首先在桌面上创建a.txt文件,其内容如图1所示。
图1 a.txt文件
获取此文件的位置指针对文件进行随机读写,代码如例1所示:
例1
1 #include <iostream>
2 #include<fstream>
3 using namespace std;
4 int main()
5 {
6 ifstream ifs; //构造输入流对象
7 ifs.open("C:\\Users\\www\\Desktop\\a.txt", ios::in | ios::out | ios::binary);
8 cout << "ifs first: " << ifs.tellg() << endl; //打开文件后查看指针位置
9 ifs.seekg(6); //将位置指针向后移动6个字节
10 cout << "ifs second: " << ifs.tellg() << endl; //移动指针后再查看指针位置
11 char ch;
12 ifs.get(ch); //获取当前指针处的字符
13 cout << "get cur char: " << ch << endl;
14
15 ofstream ofs; //构造输出流对象
16 ofs.open("C:\\Users\\www\\Desktop\\a.txt", ios::in | ios::out | ios::binary);
17 cout << "ofs first: " << ofs.tellp() << endl; //输出流打开文件后,查看指针位置
18 ofs.seekp(3); //将指针向后移动3个字节
19 cout << "ofs second: " << ofs.tellp() << endl; //设置后再查看指针位置
20 ofs.put('A'); //向当前指针处写入字符A,替换掉原来的字符
21 ifs.seekg(ios::beg); //将输入流的文件位置指针移动到开头
22 char buf[20];
23 while (!ifs.eof()) //读取文件并输出
24 {
25 ifs.getline(buf, 20, '\n');
26 cout <<"buf: "<< buf << endl;
27 }
28 ifs.close();
29 ofs.close();
30
31 system("pause");
32 return 0;
33 }
运行结果如图2所示。
图2 例1运行结果
由图2可知,当输入流对象ifs打开文件时其指针是指向文件开头处,当设置指针向后移动6个字节后,则指针位置变成了6,此时读取这个位置的字符是’z’,与a.txt文件第6个位置的字符相匹配。
当输出流对象ofs打开文件时文件指针也是指向文件开头处,当设置指针向后移动3个字节后,则指针位置变成了3,此时向该位置处写入一个字符’A’,将原来此处的字符替换,再把输入流指针移到开头,从头读取文件内容并输出,由输出结果看到,位置3处的字符’a’被替换成了’A’。