前一个用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; }