程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++文件打包工具實現

c++文件打包工具實現

編輯: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);
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved