C++编写一个文件打包工具

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <error.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];//文件名
};

//制作CAB文件的类对象
class MyCab
{
private:

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

public:

 //无参数构造
 MyCab()
 {
  memset(&fh,0x0,sizeof(fh));
  memset(ObjectFilePathName,0x0,sizeof(ObjectFilePathName));
 }

public:

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

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

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

 //制作打包文件
 void 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);
  }

  //开始合并写文件
  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 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];
   char *ptmpC = fh.FileName[i] + strlen(fh.FileName[i]);
   while( '\\' != *ptmpC)
   {
    ptmpC--;
   }
   memset(tmpFileName,0x0,sizeof(tmpFileName));
   strcpy(tmpFileName,ptmpC+1);
   //取CAB文件路径
   char tmpPathName[MAX_PATH];
   memset(tmpPathName,0x0,sizeof(tmpPathName));
   strcpy(tmpPathName,CabFilePathName);
   ptmpC = tmpPathName + strlen(tmpPathName);
   while('\\' != *ptmpC)
   {
    ptmpC--;
   }
   ptmpC++;
   *ptmpC = '\0';
   strcat(tmpPathName,tmpFileName);
   pWork = fopen(tmpPathName,"wb");
   fwrite(pTmpData,fh.FileLen[i],1,pWork);
   fclose(pWork);
   delete [] pTmpData;
  }

  fclose(pCAB);
 }

private:

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

//使用方法:
void main(void)
{
 //--------------------打包过程--------------------
 //声明对象
 MyCab mc;
 //设置输出文件
 mc.SetOutPutFile("d:\\mycabs\\my.cab");
 //添加要打包的文件
 mc.AddFile("c:\\aa.jpg");
 mc.AddFile("c:\\aa.xls");
 //执行打包
 mc.DoMakeCAB();

 //--------------------解过程--------------------
 //声明对象
 MyCab umc;
 //执行解包
 umc.DoUnCAB("d:\\mycabs\\my.cab");

cin.clear();
 cin.get();
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值