前一个用C++写的程序比较粗糙,也不规范,无法体现出C++的强大.这个程序里我扩展了一个恢复png文件的功能.png文件的恢复方法跟BMP文件的恢复方法不同,这个程序我尽量使用C++语言,并采用了一个泛型算法来恢复.速度上我觉得没有C语言快,我以后再写个C的版本进行比较一下.
Raw.h
#include <windows.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class MyApp
{
public:
VOID init(LPCTSTR lp);
HANDLE f;
DWORD fsize;
UINT fpoint;
};
class Raw
{
public:
virtual VOID GetName(char* c)=0;
virtual UINT ComRaw()=0;
VOID Recover(UINT nCount);
protected:
VOID Read(void* lpBuf,UINT nCount);
VOID Write(LPCTSTR lp,void* lpBuf,UINT nCount);
};
class BmpRaw : public Raw
{
public:
VOID GetName(char* c);
virtual UINT ComRaw();
private:
struct BmpHeader{
WORD ND;
WORD TYPE;
UINT size;
WORD r1;
WORD r2;
}bh;
};
class PngRaw : public Raw
{
public:
VOID GetName(char* c);
PngRaw(UINT ms);
UINT ComRaw();
private:
UINT maxsize;
vector<CHAR> PngHeader ;
vector<CHAR> PngFooter ;
};
Raw.cpp
#include "Raw.h"
MyApp app;
void main()
{
try
{
app.init("img");
BmpRaw br;
PngRaw pr(5*1024*1024);
Raw* r[]={&br,&pr};
while (1)
{
for (int j=0;j<sizeof(r)/4;j++)
{
r[j]->ComRaw();
}
app.fpoint+=512;
}
}
catch (char *c)
{
cerr << c <<endl;
}
}
// Raw Class
VOID Raw::Recover(UINT nCount)
{
char fname[20];
char *dout=new char[nCount];
Read(dout,nCount);
GetName(fname);
Write(fname,dout,nCount);
delete [] dout;
}
VOID Raw::Read(void* lpBuf,UINT nCount)
{
DWORD Num;
if ( app.fpoint > app.fsize)
{
throw "scan end";
}
::SetFilePointer(app.f,app.fpoint,NULL,FILE_BEGIN);
::ReadFile(app.f,lpBuf,nCount,&Num,NULL);
}
VOID Raw::Write(LPCTSTR lp,void* lpBuf,UINT nCount)
{
DWORD Num;
HANDLE fout;
fout=::CreateFile(lp,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
::WriteFile(fout,lpBuf,nCount,&Num,NULL);
CloseHandle(fout);
}
// BmpRaw Class
UINT BmpRaw::ComRaw()
{
Read(&(bh.TYPE),10) ;
if(bh.TYPE==MAKEWORD('B','M')&&bh.r1==0&&bh.r2==0)
{
Recover(bh.size);
return bh.size;
}
else
{
return 0;
}
}
VOID BmpRaw::GetName(char* c)
{
sprintf(c,"%d.bmp",app.fpoint);
}
// PngRaw Class
VOID PngRaw::GetName(char* c)
{
sprintf(c,"%d.png",app.fpoint);
}
PngRaw::PngRaw(UINT ms)
{
maxsize=ms;
const CHAR ph[8] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
PngHeader.resize(8);
memcpy(&PngHeader[0],ph,8);
const CHAR pf[8] = { 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 };
PngFooter.resize(8);
memcpy(&PngFooter[0],pf,8);
}
UINT PngRaw::ComRaw()
{
vector<CHAR> temp(8);
Read(&temp[0],8) ;
if (temp==PngHeader)
{
vector<char> tempdata(maxsize);
Read(&tempdata[0],maxsize);
vector<char>::iterator iter;
iter=search(tempdata.begin(),tempdata.end(),PngFooter.begin(),PngFooter.end());
Recover((UINT)(iter-&tempdata[0]+8));
return (UINT)(iter-&tempdata[0]+8);
}
return 0;
}
// MyApp Class
VOID MyApp::init(LPCTSTR lp)
{
f=::CreateFile(lp,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(f==INVALID_HANDLE_VALUE){throw "can't open file";}
fsize=::GetFileSize(f,NULL);
fpoint=0;
}
转载于:https://blog.51cto.com/jzhdd/1338073