WIN32编程入门学习暂告一段落,晚上睡觉的时候不知怎的想到了二进制的文件读写。
在我的工作中,有一部分的.dat文件,那是需要用专门的软件来查看数据的,
我总是试图找出它的结构自己写个小程序来读取内容但始终没有头绪。
仔细想来,在学习C/C++的这段时间里,文本文件的读写,.csv文件的读写及数据处理做过2个小程序练手,
还算有点思路;但根本没有注意更谈不上练习二进制文件的读写,所有我所有的试图也只是试图而已,目前为止还根本无法实现。
那么,要想实现它,我需要怎么做? 我开始百度/开始寻找路径:
1. C语言的二进制文件基本操作命令会使用:
FILE *pFile = NULL;
pFile = fopen("d:/a.dat", "rb");
if (!pFile) //文件打开失败
{
puts("File Open Error");
exit(-1);
}
puts("File Open Success!");
//各种操作
fclose(pFile); //关闭文件
2. 但读写文本文件时更多的使用[fpus][fgets] ,而几乎不会去使用[fwrite][fread];
关键的点在于二进制文件需要使用到[fread],而使用这个函数你需要知道每次要读多少个字节,读几次,
而且还要把这些读出的字节,存到一个数组或结构体中,如果不知道二进制的数据结构,那么便无从下手!
fread(buffer,size,count,fp);
//buffer是一个指针,指向数据的首地址, size表示数据块的字节数, count表示操作几次,fp是文件指针
fwrite(buffer,size,count,fp);
二进制文件读写的典型学习示例一般有三个:
1. 自己定义一个结构体(数组),自己给它赋值,然后写入二进制文件;
2. 用上面定义的结构体,读出二进制文件中的有效数据,在控制台上打印;
3. 不考虑二进制文件的结构,从一个二进制文件中读取一定字节数,写入另一个二进制文件(二进制文件复制)
其中第3个需要自己验证一下:如果文件后缀不同,复制出的文件的结构体虽然相同,能否被应用软件打开的。(例如复制一个.bmp变成.jpg)
附网上搜到的C++对二进制文件的读写文章:
C++对二进制文件的读写操作 作者:C语言中文网的站长, (http://c.biancheng.net/cpp/html/2957.html) http://c.biancheng.net/cpp/biancheng/view/260.html
一些不相关的资源(单片机):http://c.biancheng.net/cpp/danpianji/ |
C还是C++,或者都需要?目前我只能说,C++的确用起来比C要轻松一些,只是要花上很多的时间学了后才行。
3. 所以,要试图读取一个.dat文件的有效数据,首先要知道它的数据结构。但是从哪里得到它的结构体呢?
于是,我百度到了一篇文章:
二进制代码中数据结构的逆向挖掘 作者:未署名 |
在这篇文章中,我了解到了“数据结构逆向”,以及其包括两个方面:
1. 推导给定二进制应用程序的数据结构定义,
2. 推导特定内存片段的数据结构实例。
也就是说,如果你没有这个文件的数据结构,要么你通过逆向的技术或工具软件来获得它。只不过,目前而言,我还一个正向的实例都没有实践过,何以谈逆向?
随着实践经验的增加,先了解和熟悉常用的(已经结构)的文件如何读取(比如.bmp,.mp3,.word),然后再来谈怎样从一个简单结构的文件中,推断出它的结构体。
对于.dat文件:DAT并不是一种标准文件。许多软件都使用这个扩展名,但文件含义不同
.dat文件是程序使用的数据,它只是开发者为了清楚文件的意思而自己定义的,也可以命名成别的扩展名!
.dat文件的打开工具也不一样,比如有些其实是文本文件,只是将扩展名改写成.dat,最常见的还有VCD影音文件等
4. 我的第一个二进制文件的结构学习(BMP)
4.1 首先,用mspaint新建一个文件,另存为h1.bmp的单色位图,右键查看文件信息如下:
4.2 使用EDITPLUS打开文件,以16进制查看:
BMP的结构在wingdi.h中有定义,可以使用IDE查看,根据结构中每个变量所占的字节数,可以了解文件情况:
1. 4D 42 :此字段的值总为‘BM’
2. 00 01 CB 3E :BMP图像文件的大小
3. 00 00 00 3E :BMP图像数据的地址
5. 00 00 03 EE:BMP图像的宽度,单位像素
6. 00 00 03 96 :BMP图像的高度
7. 00 01 : BMP图像的色深,即一个像素用多少位表示,常见有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色
8. 00 00 00 00: 压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定
在前面的C程序中加入:
BITMAPFILEHEADER bHead, *p;
p = &bHead;
int si = sizeof(bHead);
BITMAPINFOHEADER bInfo, *q;
q = &bInfo;
int qi = sizeof(bInfo);
RGBQUAD bRGB[1], *p2;
p2 = bRGB;
int sizeP2 = sizeof(bRGB);
fread(p,1,si,pFile);
fread(q,qi,1,pFile);
fread(p2,sizeP2,1,pFile);
断点调试,在IDE中查看到数据如下:可以看到对应的数据与文件右键属性是一致的:
至此,我终于实践了一个二进制文件,向前跨出了一步~
参考:
BMP文件结构 作者:未知(转自网络) http://www.cnblogs.com/kingmoon/archive/2011/04/18/2020097.html |
位图文件的结构是非常容易找到,包括各种学习资源和别人经验总结,比如说下面这篇文章就相当不错:
浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beerhttp://beer.cnblogs.com/ 地址:http://www.cnblogs.com/beer/archive/2010/11/21/1883054.html |