二进制文件读写那些事儿(C++实现)

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; 二进制文件的读写很简单,就像加密解密一样。在读取时,只要知道其间的约定格式就可以将我们所需要的数据读出,其中主要涉及到指针的操作,大家在读取时一定要搞清楚每个数据类型所占用的字节数。

参考:
https://blog.csdn.net/albert528108/article/details/21710321
http://m.biancheng.net/view/1538.html
http://c.biancheng.net/view/302.html

  • 15
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值