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; }

 

转载于:https://www.cnblogs.com/hewei2012/archive/2012/11/28/2792448.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值