zoukankan      html  css  js  c++  java
  • c++文件打包工具实现

    没事做就来写一个打包的工具吧。很多是网络上面找的,只是我把他修改一下合并在一起。




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


    #include "stdafx.h"
    #include "SerchAllFile.h"
    #include "MyCab.h"


    int _tmain(int argc, _TCHAR* argv[])
    {
    vector<string> vec_file;
    vector<string>::iterator itemFileName;
    char filePacketPath[MAX_PATH] = "E:\huangyushi\测试写的实例";
    char filePutPath[MAX_PATH] = "d:\fasdfasdf\my.cab";
    CSerchAllFile::getInstance()->get_filelist(filePacketPath, vec_file);




    //--------------------打包过程--------------------
    //声明对象
    CMyCab mc;
    //设置输出文件
    mc.SetOutPutFile(filePutPath);
    //添加要打包的文件
    for (itemFileName=vec_file.begin(); itemFileName<vec_file.end(); itemFileName++)
    {
    mc.AddFile((*itemFileName).c_str());
    }
    //执行打包
    mc.DoMakeCAB();


    //--------------------解过程--------------------
    //声明对象
    CMyCab umc;
    //执行解包
    umc.DoUnCAB(filePutPath);


    cin.clear();
    cin.get();


    return 0;

    }


    -----------------------------------------------------------------------------------------------------------------------

    打包一个文件下面的文件,我要先要做的就是遍历查找里面的文件,并将文件全部记录起来(通过get_filelist()方法我们可以得到对应的文件路径并保存到一个vector里面)

    #pragma once


    #include <string>
    #include <vector>
    #include <fstream>
    #include <windows.h>
    #include <iostream>
    #include <conio.h>


    using namespace std;


    class CSerchAllFile
    {
    public:
    CSerchAllFile(void);
    ~CSerchAllFile(void);
    static CSerchAllFile *getInstance();


    public:
    /*void find(char *lpPath);
    void _find(string path);*/


    void get_filelist(char *foldname,vector<string> &filelist);
    void ReadFile(const char* fileName);
    void WriteFile(string fileName);
    };




    #include "StdAfx.h"
    #include "SerchAllFile.h"


    static CSerchAllFile* instance;


    CSerchAllFile::CSerchAllFile(void)
    {
    }


    CSerchAllFile::~CSerchAllFile(void)
    {
    }


    CSerchAllFile* CSerchAllFile::getInstance()
    {
    if (instance == NULL)
    {
    instance = new CSerchAllFile();
    }


    return instance;
    }


    //遍历文件夹下的文件名列表(包括嵌套文件夹)
    void CSerchAllFile::get_filelist(char *foldname,vector<string> &filelist)
    {
    HANDLE hFind;
    WIN32_FIND_DATA fileData;
    string line;
    char fn[MAX_PATH];
    char tmpfn[MAX_PATH];
    strcpy(fn,foldname);


    //需要对文件夹名的字符串进行处理
    if(fn[strlen(fn) -1] != '\' )
    {
    strcat(fn, "\");
    }


    //留意顺序,此时fn已加入"\"
    strcpy(tmpfn,fn);
    //不加*会出错!
    strcat(fn, "*");


    hFind = FindFirstFile(fn, &fileData);
    FindNextFile(hFind, &fileData);
    while(FindNextFile(hFind, &fileData))
    {
    //如果扫描到的当前为文件夹
    if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
    if(fileData.cFileName[0]!='.')
    {
    char szFile[MAX_PATH];
    strcpy(szFile,tmpfn);
    strcat(szFile,fileData.cFileName);
    get_filelist(szFile,filelist);
    }
    }
    //扫描到文件
    else
    {
    line = (string)tmpfn;
    line+=fileData.cFileName;
    /*if (line.find(".h",0)!=string::npos)
    {
    filelist.push_back(line);
    }
    else
    {
    continue;
    }*/
    filelist.push_back(line);
    }
    //cout<<line<<endl;
    }
    }



    ---------------------------------------------------------------------------------------------------------------------

    #pragma once


    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>
    #include <string.h>
    #include <error.h>
    #include <direct.h>
    using namespace std;


    //最多打包文件个数
    #define MAX_FILE_COUNT  1024
    //最大路径字符长度
    #define MAX_PATH   260


    //文件头
    struct FileHead
    {
    unsigned int FileCount;//文件个数
    unsigned int FileLen[MAX_FILE_COUNT];//文件大小
    char FileName[MAX_FILE_COUNT][MAX_PATH];//文件名
    };


    class CMyCab
    {
    private:
    FileHead fh;//文件头
    char ObjectFilePathName[MAX_PATH];//生成打包文件位置及名称


    public:
    CMyCab(void);
    ~CMyCab(void);


    //添加文件到包内
    void AddFile(const char * FilePathName);
    //设置打包输出文件
    void SetOutPutFile(char * OutFile);
    //获取文件大小(传入以二进制方式打开的文件指针)
    long GetFileSize(FILE *pf);
    //制作打包文件
    void DoMakeCAB();
    //解包(为了节省时间不写错误处理了,可以根据上面自己添加)
    void DoUnCAB(char *CabFilePathName);


    private:
    //显示打包内文件信息
    void printCAB();
    //创建文件夹
    void CheckTargetPath(string targetPath);
    };






    #include "StdAfx.h"
    #include "MyCab.h"


    CMyCab::CMyCab(void)
    {
    memset(&fh,0x0,sizeof(fh));
    memset(ObjectFilePathName,0x0,sizeof(ObjectFilePathName));
    }


    CMyCab::~CMyCab(void)
    {
    }


    //添加文件到包内
    void CMyCab::AddFile(const char * FilePathName)
    {
    if ( fh.FileCount >= MAX_FILE_COUNT - 1 )
    {
    cout<<"最多支持"<<MAX_FILE_COUNT<<"个文件"<<endl;
    return;
    }
    strcpy(fh.FileName[fh.FileCount],FilePathName);
    fh.FileCount++;
    }


    //设置打包输出文件
    void CMyCab::SetOutPutFile(char * OutFile)
    {
    memset(ObjectFilePathName,0x0,sizeof(ObjectFilePathName));
    strcpy(ObjectFilePathName,OutFile);
    }


    //获取文件大小(传入以二进制方式打开的文件指针)
    long CMyCab::GetFileSize(FILE *pf)
    {
    //指针移到文件尾
    fseek(pf,0,/*SEEK_END*/ 2);
    return ftell(pf);
    }


    //制作打包文件
    void CMyCab::DoMakeCAB()
    {
    if ( fh.FileCount < 1 )
    {
    cout<<"没有文件添加到打包"<<endl;
    return;
    }
    if ( strlen(ObjectFilePathName) < 1 )
    {
    cout<<"没有指定打包文件输出位置"<<endl;
    return;
    }


    FILE *pOutFile = NULL;
    FILE *pWorkFile = NULL;


    //获取所有文件大小
    for ( int i = 0 ; i < fh.FileCount ; i++ )
    {
    pWorkFile = fopen(fh.FileName[i],"rb");
    if ( NULL == pWorkFile )
    {
    cout<<"文件:"<<fh.FileName[i]<<"无法读取["<<strerror(errno)<<"]"<<endl;
    return;
    }
    fh.FileLen[i] = GetFileSize(pWorkFile);
    fclose(pWorkFile);
    }


    //检查是否有对应的文件夹
    CheckTargetPath(ObjectFilePathName);
    //开始合并写文件
    pOutFile = fopen(ObjectFilePathName,"wb");
    if ( NULL == pOutFile )
    {
    cout<<"输出文件创建失败["<<strerror(errno)<<"]"<<endl;
    return;
    }


    //写入文件头
    fwrite(&fh,sizeof(fh),1,pOutFile);
    //写入各文件
    for ( int i = 0 ; i < fh.FileCount ; i++ )
    {
    unsigned char *pTmpData = NULL;
    pWorkFile = fopen(fh.FileName[i],"rb");
    if ( NULL == pWorkFile )
    {
    cout<<"文件:"<<fh.FileName[i]<<"无法读取["<<strerror(errno)<<"]"<<endl;
    fclose(pWorkFile);
    fclose(pOutFile);
    return;
    }
    pTmpData = new unsigned char[fh.FileLen[i]];
    fread(pTmpData,fh.FileLen[i],1,pWorkFile);
    if ( ferror(pWorkFile) )
    {
    cout<<"文件:"<<fh.FileName[i]<<"无法读取["<<strerror(errno)<<"]"<<endl;
    fclose(pWorkFile);
    fclose(pOutFile);
    return;
    }
    fwrite(pTmpData,fh.FileLen[i],1,pOutFile);
    if ( ferror(pOutFile) )
    {
    cout<<"文件:"<<ObjectFilePathName<<"无法写入["<<strerror(errno)<<"]"<<endl;
    fclose(pWorkFile);
    fclose(pOutFile);
    return;
    }
    delete [] pTmpData;
    fclose(pWorkFile);
    }


    fclose(pOutFile);
    cout<<"打包完成"<<endl;
    }


    //解包(为了节省时间不写错误处理了,可以根据上面自己添加)
    void CMyCab::DoUnCAB(char *CabFilePathName)
    {
    FILE *pCAB = NULL;
    FILE *pWork = NULL;


    pCAB = fopen(CabFilePathName,"rb");


    //读文件头
    memset(&fh,0x0,sizeof(fh));
    fread(&fh,sizeof(fh),1,pCAB);


    printCAB();


    //解包的所有文件放到当前目录下
    for ( int i = 0 ; i < fh.FileCount ; i++ )
    {
    unsigned char *pTmpData = NULL;
    pTmpData = new unsigned char[fh.FileLen[i]];
    fread(pTmpData,fh.FileLen[i],1,pCAB);
    //只取文件名,不要生成文件的路径名
    char tmpFileName[MAX_PATH];
    string str = "E:\huangyushi\测试写的实例\";
    string aaa;
    aaa.assign(fh.FileName[i] ,strlen(fh.FileName[i]) );
    const char *chaaaaa = aaa.replace(0, str.length(), "\").c_str();
    char ptmpC[MAX_PATH];
    strcpy(ptmpC, chaaaaa);


    memset(tmpFileName,0x0,sizeof(tmpFileName));
    strcpy(tmpFileName,ptmpC+1);
    //取CAB文件路径
    char tmpPathName[MAX_PATH];
    memset(tmpPathName,0x0,sizeof(tmpPathName));
    strcpy(tmpPathName,CabFilePathName);
    char* tmpC = tmpPathName + strlen(tmpPathName);
    while('\' != *tmpC)
    {
    tmpC--;
    }
    tmpC++;
    *tmpC = '';
    strcat(tmpPathName,tmpFileName);


    pWork = fopen(tmpPathName,"wb");
    if (pWork == NULL)
    {
    CheckTargetPath(tmpPathName);
    pWork = fopen(tmpPathName,"wb");
    }
    fwrite(pTmpData,fh.FileLen[i],1,pWork);
    fclose(pWork);
    delete [] pTmpData;
    }


    fclose(pCAB);
    }


    //显示打包内文件信息
    void CMyCab::printCAB()
    {
    cout<<"文件内信息如下:"<<endl;
    cout<<"文件总数:"<<fh.FileCount<<endl;
    for ( int i = 0 ; i < fh.FileCount ; i++ )
    {
    cout<<fh.FileName[i]<<" "<<fh.FileLen[i]<<"字节"<<endl;
    }
    }


    //创建文件夹
    void CMyCab::CheckTargetPath(string targetPath)
    {
    //Log &log = Log::getLog("main", "CheckTargetPath");
    int e_pos = targetPath.length();
    int f_pos = targetPath.find("\",0);
    string subdir;
    do
    {
    e_pos = targetPath.find("\",f_pos+2);
    if(e_pos != -1)
    {
    subdir = targetPath.substr(0,e_pos);
    if(_mkdir(subdir.c_str())==0)
    printf( "creat success %s",subdir.c_str());
    else 
    printf("creat fail %s",subdir.c_str());
    }
    f_pos = e_pos;
    }while(f_pos!=-1);
    }

  • 相关阅读:
    django使用redis
    Python连接redis
    Redis 字符串(String)
    Redis 列表(List)
    Redis 集合(Set)
    Redis 哈希(Hash)
    Python获取时间范围
    如何查看oracle当前连接数,会话数
    python装饰器
    windows通过ssh连接虚拟机中的ubuntu步骤
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3249357.html
Copyright © 2011-2022 走看看