1. 二进制文件存储的优点
为什么要使用二进制文件。原因大概有三个:
(1)二进制文件比较节约空间,这两者储存字符型数据时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间,比如储存 Real*4 的数据:3.1415927,文本文件需要 9 个字节,分别储存:3 . 1 4 1 5 9 2 7 这 9 个 ASCII 值,而二进制文件只需要 4 个字节(DB 0F 49 40)
(2)内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。
(3)就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。
通常情况下,我们保存数据到文件是默认文本文件的方式。以数字1297为例,在将其保存到文本文件中时,其被格式化为字符串的形式保存,如图1所示为此刻的存储方式。而将其以二进制的形式保存时,其最大只占用两个字节。
图1 以字符串表示的数字
图2 以二进制表示的数字
有关二进制更为详细的介绍大家可以参考文章后的链接,以下将介绍几种读取二进制的方式 。
2. 二进制文件读写操作(C++)
(1)将数据写入二进制文件
将我们所要保存的数据按照一定的格式写入到二进制文件中。
class CStudent
{
public:
char szName[20];
int age;
};
//将数据以二进制写入文件
int writeBinFile()
{
CStudent s;
ofstream outFile("students.dat", ios::out | ios::binary);
cout << "请输入学生信息:" << endl;
while (cin >> s.szName >> s.age)
outFile.write((char*)&s, sizeof(s));
outFile.close();
return 1;
}
输入学生信息:
Jack 22
Rose 20
^Z
(2)按一定数据格式读取二进制文件
按照CStudent的数据格式读取二进制文件"students.dat",源代码如下:
//从二进制文件读取数据
int readBinFile1()
{
CStudent dataType;
int bcount = 0;
ifstream inFile("students.dat", ios::in | ios::binary); //二进制读方式打开
if (!inFile) {
cout << "error" << endl;
return 0;
}
while (inFile.read((char *)&dataType, sizeof(dataType))) { //一直读到文件结束
bcount+=inFile.gcount();
cout << dataType.szName << " " << dataType.age << endl;
}
cout << "总字节数:"<< bcount << endl;
inFile.close();
}
读取的结果如下:
(3)不带任何格式读取二进制文件
有时候,我们并不知道要读取的二进制文件的格式,对此可以直接以单个字节的形式将其读出。如下所示为读取二进制文件“data.dat”的函数,其中以16进制的格式显示。
//读取任意二进制文件,不带有数据结构的
void readBinFile2()
{
ifstream fin("students.dat", ios::in | ios::binary);
if (!fin) {
cout << "open error!" << endl;
return;
}
// 将读写位置移动到文件末尾,获取文件大小
fin.seekg(0, ios_base::end);
long long firm_len = fin.tellg();
printf("size of firm: %lld\n", firm_len);
// 将读写位置移动到文件开头,申请内存,将固件内容存入 pSrcBuf
fin.seekg(0, ios_base::beg);
auto* pSrcBuf = new char[firm_len];
fin.read((char*)pSrcBuf, sizeof(char) * firm_len);
for (int i = 0; i < firm_len;) {
if (i % 16 != 0) printf(" ");
printf("%02x", (unsigned char)pSrcBuf[i]);
i++;
if (i % 16 == 0) printf("\n");
}
delete[] pSrcBuf;
}
读取"students.dat"的16进制结果:
其中可以看到学生的年龄信息0x16(22D)和0x14(20D)。
3.读取混合数据类型的二进制文件
emsp; 当我们的二进制文件是有多种数据类型的混合而成的时候,我们可以根据写入数据的顺序依次将其读出。如下代码段位通过文件流的方式读取二进制文件,除此以外还可以通过内存映射的方式进行读取。
inFile.read((char *)(dataType1), dataType1Size);
inFile.read((char *)(dataType2), dataType2Size);
inFile.read((char *)(dataType3), dataType3Size);
4.总结
emsp; 二进制文件的读写很简单,就像加密解密一样。在读取时,只要知道其间的约定格式就可以将我们所需要的数据读出,其中主要涉及到指针的操作,大家在读取时一定要搞清楚每个数据类型所占用的字节数。