📄 combinefiles.cpp
字号:
// CombineFiles.cpp: implementation of the CCombineFiles class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Ex070203a.h"
#include "CombineFiles.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//CFileInfo类
CString CFileInfo::GetFileName()
{//去掉路径
CString strFileName = m_strPathFileName ;
for( int nPos = strFileName.GetLength() - 1 ; nPos >= 0 ; nPos-- )
{
char ch = strFileName[nPos] ;
if('\\' == ch || ':' == ch || '/' == ch )
break;
}
if( -1 != nPos )
strFileName = strFileName.Mid(nPos+1);
return strFileName ;
}
int CFileInfo::Read(LPBYTE lpBuff)
{
m_nPosOfCombineFile = *(ULONG*)lpBuff ;
m_nFileSize = *(ULONG*)(lpBuff + sizeof(ULONG));
const int nFileNameLeng = *(ULONG*)(lpBuff + sizeof(ULONG)*2);
char szTemp[MAX_PATH ] = {0};
memcpy(szTemp,lpBuff + sizeof(ULONG)*3,nFileNameLeng);
m_strPathFileName = szTemp ;
return GetLeng();
}
int CFileInfo::Write(LPBYTE lpBuff)
{
CString strFileName = GetFileName() ;
int nFileNameLeng = strFileName.GetLength() ;
memcpy(lpBuff,&m_nPosOfCombineFile,sizeof(ULONG));
memcpy(lpBuff + sizeof(ULONG),&m_nFileSize,sizeof(ULONG));
memcpy(lpBuff + sizeof(ULONG)*2,&nFileNameLeng,sizeof(ULONG));
memcpy(lpBuff + sizeof(ULONG)*3,(LPCTSTR)strFileName,nFileNameLeng);
return GetLeng();
}
int CFileInfo::GetLeng()
{
CString strFileName = GetFileName() ;
int nLeng = sizeof(ULONG)*3 + strFileName.GetLength() ;
return nLeng ;
}
CCombineFiles::CCombineFiles()
{
}
CCombineFiles::~CCombineFiles()
{
}
bool CCombineFiles::InitFileInfo(FILE_INFO_ARRAY& arDataFiles,const CStringArray& arStrPathFileName)
{
for(int i = arStrPathFileName.GetSize() - 1 ; i >= 0 ; i-- )
{
CString strFileName = arStrPathFileName[i] ;
if(strFileName.IsEmpty())
continue ;
CFileStatus rStatus ;
CFile::GetStatus(strFileName,rStatus);
//取得文件长度
CFileInfo fileInfo ;
fileInfo.m_strPathFileName = strFileName ;
fileInfo.m_nFileSize = rStatus.m_size ;
//加进数组
arDataFiles.Add(fileInfo);
}
return true ;
}
//CCombineFiles类
//strCombineFileName 打包后的文件名
//arStrPathFileName 数据文件名
//strExeFile 可执行文件名,打包时会放到最前面,这样此程序才可以执行
bool CCombineFiles::Combine(CString strCombineFileName,const CStringArray& arStrPathFileName,CString strExeFile )
{
FILE_INFO_ARRAY arDataFiles ;
InitFileInfo(arDataFiles,arStrPathFileName);
ULONG nTotalSize = 0 ;
ULONG uFileInfoPos = 0 ;
ULONG uFileNum = arDataFiles.GetSize() ;
//文件信息概要占用的长度
nTotalSize += (sizeof(uFileInfoPos) + sizeof(uFileNum)) ;
//文件信息占用的长度
for(int i = arDataFiles.GetSize() - 1 ; i >= 0 ; i-- )
{
nTotalSize += arDataFiles[i].GetLeng() ;
}
//计算各文件的长度
if(!strExeFile.IsEmpty())
{
CFileStatus rStatus ;
CFile::GetStatus(strExeFile,rStatus);
nTotalSize += rStatus.m_size ;
}
for(i = arDataFiles.GetSize() - 1 ; i >= 0 ; i-- )
{
nTotalSize += arDataFiles[i].m_nFileSize ;
}
HANDLE hFile = NULL ;
HANDLE hFileMapping = NULL;
PBYTE pbFile = NULL ;
bool bSuc = true ;
ULONG nPos = 0 ;
hFile = CreateFile(strCombineFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( INVALID_HANDLE_VALUE == hFile )
{
bSuc = false ;
goto End ;
}
hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,
0, nTotalSize , NULL);
if( NULL == hFileMapping )
{
bSuc = false ;
goto End ;
}
pbFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0,0, nTotalSize);
if( NULL == pbFile )
{
bSuc = false ;
goto End ;
}
//复制Exe数据
{
if(!strExeFile.IsEmpty())
{
CFile file ;
file.Open(strExeFile , CFile::modeRead);
int nFileLeng = file.GetLength() ;
file.Read(pbFile+nPos,nFileLeng);
nPos += nFileLeng ;
file.Close();
}
}
//复制其他文件数据
for(i = arDataFiles.GetSize() - 1 ; i >= 0 ; i-- )
{
arDataFiles[i].m_nPosOfCombineFile = nPos ;
CFile file ;
file.Open(arDataFiles[i].m_strPathFileName , CFile::modeRead);
file.Read(pbFile+nPos,arDataFiles[i].m_nFileSize);
nPos += arDataFiles[i].m_nFileSize ;
file.Close();
}
uFileInfoPos = nPos ;
//写文件信息
for(i = arDataFiles.GetSize() - 1 ; i >= 0 ; i-- )
{
nPos += arDataFiles[i].Write(pbFile+nPos);
}
//写文件概要信息
memcpy(pbFile+nPos,&uFileNum,sizeof(ULONG));
nPos += sizeof(ULONG);
memcpy(pbFile+nPos,&uFileInfoPos,sizeof(ULONG));
End :
if( NULL != pbFile )
UnmapViewOfFile(pbFile);
if( NULL != hFileMapping )
CloseHandle(hFileMapping);
if( INVALID_HANDLE_VALUE != hFile)
CloseHandle(hFile);
return bSuc ;
}
//strCombineFileName 打包后的文件名
//arStrPathFileName 包含数据文件的文件夹
//strExeFile 可执行文件名,打包时会放到最前面,这样此程序才可以执行
bool CCombineFiles::Combine(CString strCombineFileName,CString strPathName,CString strExeFile )
{
CStringArray arFileNames ;
if(!GetFiles(arFileNames,strPathName))
return false ;
return Combine(strCombineFileName,arFileNames,strExeFile);
}
//strCombineFileName 要解压的文件名
//strOutDir 解压的目录
bool CCombineFiles::Extract(CString strCombineFileName,CString strOutDir)
{
if(strOutDir.IsEmpty())
return false;
if('\\' != strOutDir.Right(1) )
strOutDir += '\\' ;
int i = 0 ;
FILE_INFO_ARRAY arDataFiles ;//记录要解压后的文件的信息
CFileStatus rStatus ;
CFile::GetStatus(strCombineFileName,rStatus);
ULONG nTotalSize = rStatus.m_size ;
ULONG uFileInfoPos = 0 ;
ULONG uFileNum = 0 ;
HANDLE hFile = NULL ;
HANDLE hFileMapping = NULL;
PBYTE pbFile = NULL ;
bool bSuc = true ;
ULONG nPos = 0 ;
hFile = CreateFile(strCombineFileName,
GENERIC_READ ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( INVALID_HANDLE_VALUE == hFile )
{
bSuc = false ;
goto End ;
}
hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,
0, nTotalSize , NULL);
if( NULL == hFileMapping )
{
bSuc = false ;
goto End ;
}
pbFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0,0, nTotalSize);
if( NULL == pbFile )
{
bSuc = false ;
goto End ;
}
//读取文件概要信息
uFileNum = *(ULONG*)(pbFile + nTotalSize - sizeof(uFileNum) - sizeof(uFileInfoPos));
uFileInfoPos = *(ULONG*)(pbFile + nTotalSize - sizeof(uFileNum) );
//读取文件信息
arDataFiles.RemoveAll();
for( i = 0 ; i < uFileNum ; i++ )
{
CFileInfo fileInfo ;
uFileInfoPos += fileInfo.Read(pbFile + uFileInfoPos);
arDataFiles.Add(fileInfo);
}
for( i = 0 ; i < uFileNum ; i++ )
{
CFileInfo& fileInfo = arDataFiles[i] ;
CString strPathFileName = strOutDir + fileInfo.m_strPathFileName ;
CFile file;
file.Open(strPathFileName,CFile::modeCreate | CFile::modeWrite);
file.Write(pbFile + fileInfo.m_nPosOfCombineFile,fileInfo.m_nFileSize);
file.Close();
}
End :
if( NULL != pbFile )
UnmapViewOfFile(pbFile);
if( NULL != hFileMapping )
CloseHandle(hFileMapping);
if( INVALID_HANDLE_VALUE != hFile)
CloseHandle(hFile);
return bSuc ;
}
bool CCombineFiles::GetFiles(CStringArray &arFileNames, CString strPathName)
{
if(strPathName.IsEmpty())
return false;
if('\\' != strPathName.Right(1) )
strPathName += '\\' ;
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(strPathName + "*.*",&fd);
if (hFind != INVALID_HANDLE_VALUE)
{
while (::FindNextFile(hFind,&fd))
{
//判断是否为目录
if (!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
{
arFileNames.Add(strPathName + fd.cFileName);
}
}
::FindClose(hFind);
}
else
return false ;
return true ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -