windows API 简单合并文件和解压文件方法

// incorporate.cpp : Defines the entry point for the console application.

//



#include "stdafx.h"

#include "assert.h"

#include "stdio.h"

#include<windows.h>

#include <fstream>

#include <iostream>

#include <string>

using namespace std;



//所有资源文件

#define ALL_RES_FILE "allres.dat"

//资源文件表

#define RES_TABLE_FILE "restable.dat"



//单字节、双字节互转

static char * wstrTostr(const wchar_t * lpcwszStr){

    DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);

    char *psText = NULL;

    psText = (char*)malloc(dwNum*sizeof(char));

    if(!psText)

    {

        free(psText);

        psText = NULL;

    }

    WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);

    return psText;

}



static wchar_t * strToWstr(const char * lpcwszStr){

    DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, NULL, 0);

    wchar_t *psText = NULL;

    psText = (wchar_t*)malloc(dwNum*sizeof(wchar_t));

    if(!psText)

    {

        free(psText);

        psText = NULL;

    }

    MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, psText, dwNum);  

    return psText;

}





class CFile{

private:

    //压缩

    fstream foutTable;

    fstream foutData;

    int  m_nOffest;



    //解压

    fstream finTable;

    fstream finData;



public:

    CFile(){}



    void filemode(bool bCombine)

    {

        if(bCombine == true)

        {

            foutTable.open(RES_TABLE_FILE, ios::binary | ios::out);

            foutData.open(ALL_RES_FILE, ios::binary | ios::out);

            m_nOffest = 0;

            compress("res/");

        }

        else

        {

            finTable.open(RES_TABLE_FILE, ios::binary | ios::in);

            finData.open(ALL_RES_FILE, ios::binary | ios::in);

            deCompress();

        }

    }



    void deCompress()

    {

        assert(finTable != 0 && finData != 0);



        finTable.seekg(0, ios::end);

        int nSize = finTable.tellg();

        finTable.seekg(0, ios::beg);



        fstream fout;

        int nOffest = 0;

        while (nOffest < nSize)

        {

            short nFileNameLen;

            char * szFileName = NULL;

            int nFileOffest, nFileSize;

            char * pData = NULL;

            finTable.read((char *)&nFileNameLen, sizeof(short));

            nOffest += sizeof(short);

            szFileName = (char*)malloc(nFileNameLen + 1);

            memset(szFileName, 0, nFileNameLen + 1);

            finTable.read(szFileName, nFileNameLen);

            nOffest += nFileNameLen;

            finTable.read((char *)&nFileOffest, sizeof(int));

            nOffest += sizeof(int);

            finTable.read((char *)&nFileSize, sizeof(int));

            nOffest += sizeof(int);



            pData = (char*)malloc(nFileSize);

            finData.seekg(nFileOffest, ios::beg);

            finData.read(pData, nFileSize);



            createDirectory(szFileName);

            fout.open(szFileName, ios::binary | ios::out);

            if(fout)

            {

                fout.write(pData, nFileSize);

                fout.close();

            }



            if(szFileName != NULL)

                free(szFileName);

            if(pData != NULL)

                free(pData);

        }

    }



    void createDirectory(const char * filePath)

    {

        assert(filePath);



        int length = strlen(filePath);

        const int c_DirArrayLen = 512;



        char szDirectory[c_DirArrayLen];

        const char * szPos = NULL;

        const char * tmp = filePath;

        szPos = strchr(tmp, '/');

        while(szPos != NULL)

        {

            memset(szDirectory, 0, c_DirArrayLen);

            memcpy(szDirectory, filePath, szPos - filePath);

            wchar_t * wszDirectory = strToWstr(szDirectory);

            if (GetFileAttributes(wszDirectory) != FILE_ATTRIBUTE_DIRECTORY)

                CreateDirectory(wszDirectory, NULL);

            free(wszDirectory);

            tmp = szPos + 1;

            szPos = strchr(tmp, '/');

        }

    }





    void writeToFile(char * fileName)

    {

        assert(fileName);

        fstream fin;

        fin.open(fileName, ios::binary | ios::in);

        if(fin)

        {

            fin.seekg(0, ios::end);

            int nFileSide = fin.tellg(); 



            //先写table表

            short nNameLen = strlen(fileName);

            //先写名字

            foutTable.write((char*)&nNameLen, sizeof(short));

            foutTable.write(fileName, nNameLen);

            //写偏移量

            foutTable.write((char*)&m_nOffest, sizeof(int));

            //写文件大小

            foutTable.write((char*)&nFileSide, sizeof(int));



            //写内容

            char * szContext = (char*) malloc(nFileSide);

            fin.seekg(0, ios::beg);

            fin.read(szContext, nFileSide);

            foutData.write(szContext, nFileSide);

            free(szContext);



            m_nOffest += nFileSide;

            fin.close();

        }

    }



    //遍历res文件夹中所有文件

    void compress(const char* lpPath){

        assert(lpPath);



        char szFind[100];

        char szFile[100];

        WIN32_FIND_DATA FindFileData;

        strcpy_s(szFind,lpPath);

        strcat_s(szFind,"*.*");

        wchar_t * wszFind = strToWstr(szFind);

        HANDLE hFind=FindFirstFile(wszFind,&FindFileData);

        delete []wszFind;

        if (INVALID_HANDLE_VALUE == hFind)

            return;



        while(true)

        {

            if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)

            {

                if (FindFileData.cFileName[0]!='.')

                {

                    strcpy_s(szFile,lpPath);

                    char * pFileName = wstrTostr(FindFileData.cFileName);

                    strcat_s(szFile,pFileName);

                    strcat_s(szFile,"/");

                    free(pFileName);

                    compress(szFile);

                }

            }

            else

            {

                char * pFileName = wstrTostr(FindFileData.cFileName);

                char pFilePath[100] = {0};

                strcpy_s(pFilePath,lpPath);

                //strcat_s(pFilePath,"/");

                strcat_s(pFilePath,pFileName);

                writeToFile(pFilePath);

                free(pFileName);

            }

            if (!FindNextFile(hFind,&FindFileData))

                break;

        }

        FindClose(hFind);



    }



    ~CFile(){

        if(foutTable != 0)

            foutTable.close();

        if(foutData != 0)

            foutData.close();

        if(finTable != 0)

            finTable.close();

        if(finData != 0)

            finData.close();

    }

};



ostream & green(ostream & s)

{

    HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleTextAttribute(hstdhadle, FOREGROUND_GREEN|FOREGROUND_INTENSITY);

    return s;

}



ostream & white(ostream & s)

{

    HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleTextAttribute(hstdhadle, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);

    return s;

}



int main(int argc, char* argv[]/* f */)

{

    //说明

    if(argc >= 2 && strcmp(argv[1], "/?") == 0)

    {

        cout << green << "参数:decompress:" << "解压" << endl;

        cout << "restable.dat格式:" << endl << "    2byte:文件名长度n;" << endl;

        cout << "    'n'byte:文件名内容;" << endl;

        cout << "    4byte:文件的偏移位置;" << endl;

        cout << "    4byte:文件大小;" << white << endl;

        return 0;

    }



    CFile * file = new CFile();

    if(argc >= 2 && strcmp(argv[1], "decompress") == 0)

    {

        file->filemode(false);

        delete(file);
     return 0; } remove(RES_TABLE_FILE); remove(ALL_RES_FILE); file->filemode(true); delete(file);
return 0; }

 

你可能感兴趣的:(windows)