數據恢復軟件(四):使用C++擴展恢復功能

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章