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 = '\0';
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]<<"\t\t\t\t"<<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);
}
c++文件打包工具实现的更多相关文章
- DropDMG for Mac(dmg 文件打包工具)破解版安装
1.软件简介 DropDMG 是 macOS 系统上的一款帮助用户快速打包 DMG 文件的 Mac 文件管理软件,DropDMG 不但可以将影像档加密.更可以配合 GZip .BZip2 .Ma ...
- 软件打包为exe NSIS单文件封包工具V2.3
NSIS单文件封包工具V2.3 这是一款基于NSIS模块的封包制作工具,lzma算法最大压缩率,支持制作单文件,以及NSIS自定义解压封包. 支持注册dll,exe,reg,bat文件 默认提取设置程 ...
- 写你自己 android 多通道打包工具 可以包libs和.so文件
android上传应用程序,需要区分各个信道. 通常更改配置文件中的一个通道id,假设有多个通道,手动更改并生成apk这将是非常麻烦的,及增加误差的概率. 在这个课堂上分享一个打包工具.也可在网上类似 ...
- 以libfuse为例介绍rpm打包工具rpmbuild的使用和SPEC文件的编写
一.rpmbuild命令的安装 yum install rpm-build 二.用法 rpmbuild -bb XXXX.spec或者rpmbuild -ba XXX.tar.gz 三.目录概述 rp ...
- java将文件打包成ZIP压缩文件的工具类实例
package com.lanp; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ja ...
- webpack-bundle-analyzer打包文件分析工具
一.安装 npm intall webpack-bundle-analyzer –save-dev 二.配置 在build/webpack.prod.config.js中的module.exports ...
- 细说前端自动化打包工具--webpack
背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...
- Atitit.项目修改补丁打包工具 使用说明
Atitit.项目修改补丁打包工具 使用说明 1.1. 打包工具已经在群里面.打包工具.bat1 1.2. 使用方法:放在项目主目录下,执行即可1 1.3. 打包工具的原理以及要打包的项目列表1 1. ...
- Webpack:前端资源模块化管理和打包工具
一.介绍: Webpack 是当下最热门的前端资源模块化管理和打包工具.它可以将许多松散的模块按照依赖和规则打包成符合生 产环境部署的前端资源.还可以将按需加载的模块进行代码分隔,等到实际需要的时候再 ...
随机推荐
- eclipse:刪除空行
ctrl+F:選擇正則,輸入:^\s*\n ,點擊 replace all.
- VirtualBox上的Ubuntu附加功能
主机:Windows 10家庭中文版,VirtualBox 版本 5.2.22 r126460 (Qt5.6.2),Ubuntu 18.04, 在主机上安装了VirtualBox,然后在Virtual ...
- Oracle数据库常用Sql语句大全
一,数据控制语句 (DML) 部分 1.INSERT (往数据表里插入记录的语句) INSERT INTO 表名(字段名1, 字段名2, ……) VALUES ( 值1, 值2, ……); INSE ...
- C++ code:prime decision
1 判断一个数是否为素数 对于判断一个数m是否为素数,最朴素的方式是按照素数的定义,试除以从2开始到m-1的整数,倘若无一例外地不能整除,则该数必为素数. #include<iostream&g ...
- Java列表、数组、字符串
列表(list) list中添加,获取,删除元素 添加方法是:.add(e): 获取方法是:.get(index): 删除方法是:.remove(index), 按照索引删除: .remove(Obj ...
- javaFX中解决填充(拉伸)问题
1.margin设置实现 在项目过程中,遇到此问题,如图: 如果窗口缩小,HBox(左边的包含TitledPane那部分)看不到底部 如果窗口拉大,下面就出现空白,HBox高度没拉神 办法:对包含HB ...
- C#中IEnumerable、ICollection、IList、IQueryable 、IQueryable 、List之间的区别
一:一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Reset ...
- SpringMVC集成springfox-swagger2自动生成接口文档
本节内容: 什么是Swaggger Springfox与Swagger的关系 SpringMVC集成springfox-swagger2 一.什么是Swaggger Swagger是一个流行的API开 ...
- python:从迭代器,到生成器,再到协程的示例代码
程序员,没事多练练, 并发,并行编程,算法,设计模式, 这三个方面的知识点,没事就要多练练,基本功呀. class MyIterator: def __init__(self, element): s ...
- Angular 中后台前端解决方案 - Ng Alain 介绍
背景 之前项目使用过vue.js+iview,习惯了后端开发的我,总觉得使用不习惯,之前分析易企秀前端代码,接触到了angular js,完备的相关功能,类似后端开发的体验,让人耳目一新,全新的ang ...