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

要求能够将多个文件合并为一个文件,并且能够将被打包文件再次释放。在线等答案,谢谢... 要求能够将多个文件合并为一个文件,并且能够将被打包文件再次释放。
在线等答案,谢谢
展开
 我来答
moxsone
推荐于2016-09-01 · TA获得超过3333个赞
知道大有可为答主
回答量:2796
采纳率:50%
帮助的人:1546万
展开全部
/*
要求能够将多个文件合并为一个文件,并且能够将被打包文件再次释放。
*/
#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条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式