c++ rar 解压缩数据

261 篇文章 10 订阅

// RarSample.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include  <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <minwindef.h>

#include  "dll.hpp"

using namespace std;

enum EUNRAR_RESULT
{
    UNRARRST_SUCCESS = 0,           // 解压成功
    UNRARRST_UNKNOWN,               // 未知错误

    // 压缩包读取结果
    UNRARRST_READ_NO_MEMORY,        // 内存不足
    UNRARRST_READ_EOPEN,            // 压缩包打开错误
    UNRARRST_READ_BAD_ARCHIVE,      // 不是一个正确的rar压缩包
    UNRARRST_READ_BAD_DATA,         // 压缩包头损坏

    // 压缩包解压结果
    UNRARRST_UN_UNKNOWN_FORMAT,     // 未知的压缩包格式
    UNRARRST_UN_BAD_ARCHIVE,        // 卷不是有效的Rar文件
    UNRARRST_UN_ECREATE,            // 文件创建错误
    UNRARRST_UN_EOPEN,              // 文件打开错误
    UNRARRST_UN_ECLOSE,             // 文件关闭错误
    UNRARRST_UN_EREAD,              // 读取错误
    UNRARRST_UN_EWRITE,             // 写入错误
    UNRARRST_UN_BAD_DATA,           // 文件CRC错误
    UNRARRST_UN_MISSING_PASSWORD,   // 错误的密码
};

struct SUNRAR_INFO
{
    RARHeaderData   m_HeaderData;               // 文件头数据
    DWORD           m_dwUnrarBytesInCurrtFile;  // 当前文件的解压字节数
    DWORD           m_dwTotalUnrarBytes;        // 当前压缩包的解压字节数
    DWORD           m_dwPackSize;               // 压缩包大小
    DWORD           m_dwUnrarCurrtFile;         // 当前解压的文件数量
    DWORD           m_dwFileCount;              // 总文件数量
}g_UnrarInfo;

char chProcess[256] = "";
char chCurrtUnrarFile[512] = "";

EUNRAR_RESULT ExtractArchive(char *ArcName);
int CALLBACK CallbackProc(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2);


EUNRAR_RESULT ExtractArchive(char* ArcName, char *DestPath)
{
    EUNRAR_RESULT result = UNRARRST_SUCCESS;

    HANDLE hArcData;
    int RHCode = 0;
    int PFCode = 0;
    char CmtBuf[16384];

    RAROpenArchiveDataEx OpenArchiveData;
    memset(&OpenArchiveData, 0, sizeof(OpenArchiveData));

    OpenArchiveData.ArcName = ArcName;
    OpenArchiveData.CmtBuf = CmtBuf;
    OpenArchiveData.CmtBufSize = sizeof(CmtBuf);
    OpenArchiveData.OpenMode = RAR_OM_EXTRACT;
    OpenArchiveData.Callback = CallbackProc;
    OpenArchiveData.UserData = 0;
    hArcData = RAROpenArchiveEx(&OpenArchiveData);

    // 处理读取错误信息
    if (OpenArchiveData.OpenResult != 0)
    {
        switch (OpenArchiveData.OpenResult)
        {
        case ERAR_NO_MEMORY:
            result = UNRARRST_READ_NO_MEMORY;
            break;
        case ERAR_EOPEN:
            result = UNRARRST_READ_EOPEN;
            break;
        case ERAR_BAD_ARCHIVE:
            result = UNRARRST_READ_BAD_ARCHIVE;
            break;
        case ERAR_BAD_DATA:
            result = UNRARRST_READ_BAD_DATA;
            break;
        case ERAR_UNKNOWN:
            result = UNRARRST_UNKNOWN;
            break;
        default:
            result = UNRARRST_UNKNOWN;
            break;
        }

        return result;
    }

    // 统计压缩包相关数据
    while ((RHCode = RARReadHeader(hArcData, &g_UnrarInfo.m_HeaderData)) == 0)
    {
        PFCode = RARProcessFile(hArcData, RAR_SKIP, NULL, NULL);

        g_UnrarInfo.m_dwFileCount++;
        g_UnrarInfo.m_dwPackSize += g_UnrarInfo.m_HeaderData.PackSize;
        cout << g_UnrarInfo.m_dwFileCount << endl;
        cout << g_UnrarInfo.m_dwPackSize << endl;
    }

    RARCloseArchive(hArcData);

    hArcData = RAROpenArchiveEx(&OpenArchiveData);

    RARSetCallback(hArcData, CallbackProc, 0);

    g_UnrarInfo.m_HeaderData.CmtBuf = NULL;
    memset(&OpenArchiveData.Reserved, 0, sizeof(OpenArchiveData.Reserved));

    // 解压开始
    while ((RHCode = RARReadHeader(hArcData, &g_UnrarInfo.m_HeaderData)) == 0)
    {
        sprintf(chCurrtUnrarFile, "当前文件:%s", g_UnrarInfo.m_HeaderData.FileName);

        g_UnrarInfo.m_dwUnrarBytesInCurrtFile = 0;

        PFCode = RARProcessFile(hArcData, RAR_EXTRACT, DestPath, NULL);

        // 处理解压错误信息
        if (PFCode != 0)
        {
            switch (PFCode)
            {
            case ERAR_UNKNOWN_FORMAT:
                result = UNRARRST_UN_UNKNOWN_FORMAT;
                break;
            case ERAR_BAD_ARCHIVE:
                result = UNRARRST_UN_BAD_ARCHIVE;
                break;
            case ERAR_ECREATE:
                result = UNRARRST_UN_ECREATE;
                break;
            case ERAR_EOPEN:
                result = UNRARRST_UN_EOPEN;
                break;
            case ERAR_ECLOSE:
                result = UNRARRST_UN_ECLOSE;
                break;
            case ERAR_EREAD:
                result = UNRARRST_UN_EREAD;
                break;
            case ERAR_EWRITE:
                result = UNRARRST_UN_EWRITE;
                break;
            case ERAR_BAD_DATA:
                result = UNRARRST_UN_BAD_DATA;
                break;
            case ERAR_UNKNOWN:
                result = UNRARRST_UNKNOWN;
                break;
            case ERAR_MISSING_PASSWORD:
                result = UNRARRST_UN_MISSING_PASSWORD;
                break;
            default:
                result = UNRARRST_UNKNOWN;
                break;
            }

            return result;
        }

        g_UnrarInfo.m_dwUnrarCurrtFile++;
    }

    //压缩包头损坏
    if (RHCode == ERAR_BAD_DATA)
    {
        result = UNRARRST_READ_BAD_DATA;
    }

    RARCloseArchive(hArcData);

    return result;
}

int CALLBACK CallbackProc(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)
{
    switch (msg)
    {
        // 【处理卷改变】
    case UCM_CHANGEVOLUME:
        break;

        // 【处理解压数据】
        // P1:指向解压缩数据的地址。函数可以读取这些数据,但是不可以改变它。 
        // P2:解压缩数据的大小。需要注意,目录大小不能超过支持的最大目录的大小(Rar 3.0中,最大为4MB)
    case UCM_PROCESSDATA:
    {
        g_UnrarInfo.m_dwUnrarBytesInCurrtFile += P2;
        g_UnrarInfo.m_dwTotalUnrarBytes += P2;
    }
    break;

    // 【需要密码继续操作】
    // 当年你需要处理内部文件名也加密了的压缩包时必须处理
    // P1:指向密码缓冲的地址 P2:密码缓冲的大小
    case UCM_NEEDPASSWORD:
        break;
    }

    return 0;
}


int main(int argc, char* argv[])
{
    char *name = "C:\\Users\\14713\\Desktop\\ThirdPartyToolsCPP-master.rar";
    char *destPath = "C:\\Users\\14713\\Desktop\\1111";
    EUNRAR_RESULT result = ExtractArchive(name, destPath);
    char chResult[256];

    switch (result)
    {
    case UNRARRST_SUCCESS:
        strcpy(chResult, "解压成功!");
        break;
    case UNRARRST_UNKNOWN:
        strcpy(chResult, "未知错误!");
        break;
    case UNRARRST_READ_NO_MEMORY:
        strcpy(chResult, "内存不足!");
        break;
    case UNRARRST_READ_EOPEN:
        strcpy(chResult, "压缩包打开错误!");
        break;
    case UNRARRST_READ_BAD_ARCHIVE:
        strcpy(chResult, "不是一个正确的rar压缩包!");
        break;
    case UNRARRST_READ_BAD_DATA:
        strcpy(chResult, "压缩包头损坏!");
        break;
    case UNRARRST_UN_UNKNOWN_FORMAT:
        strcpy(chResult, "未知的压缩包格式!");
        break;
    case UNRARRST_UN_BAD_ARCHIVE:
        strcpy(chResult, "卷不是有效的Rar文件!");
        break;
    case UNRARRST_UN_ECREATE:
        strcpy(chResult, "文件创建错误!");
        break;
    case UNRARRST_UN_EOPEN:
        strcpy(chResult, "文件打开错误!");
        break;
    case UNRARRST_UN_ECLOSE:
        strcpy(chResult, "文件关闭错误!");
        break;
    case UNRARRST_UN_EREAD:
        strcpy(chResult, "读取错误!");
        break;
    case UNRARRST_UN_EWRITE:
        strcpy(chResult, "写入错误!");
        break;
    case UNRARRST_UN_BAD_DATA:
        strcpy(chResult, "文件CRC错误!");
        break;
    case UNRARRST_UN_MISSING_PASSWORD:
        strcpy(chResult, "错误的密码!");
        break;
    }
    cout << chResult << endl;
}
 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值