// incorporate.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "assert.h" #include "stdio.h" #include<windows.h> #include <fstream> #include <iostream> #include <string> using namespace std; //所有资源文件 #define ALL_RES_FILE "allres.dat" //资源文件表 #define RES_TABLE_FILE "restable.dat" //单字节、双字节互转 static char * wstrTostr(const wchar_t * lpcwszStr){ DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE); char *psText = NULL; psText = (char*)malloc(dwNum*sizeof(char)); if(!psText) { free(psText); psText = NULL; } WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE); return psText; } static wchar_t * strToWstr(const char * lpcwszStr){ DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, NULL, 0); wchar_t *psText = NULL; psText = (wchar_t*)malloc(dwNum*sizeof(wchar_t)); if(!psText) { free(psText); psText = NULL; } MultiByteToWideChar (CP_ACP, 0, lpcwszStr, -1, psText, dwNum); return psText; } class CFile{ private: //压缩 fstream foutTable; fstream foutData; int m_nOffest; //解压 fstream finTable; fstream finData; public: CFile(){} void filemode(bool bCombine) { if(bCombine == true) { foutTable.open(RES_TABLE_FILE, ios::binary | ios::out); foutData.open(ALL_RES_FILE, ios::binary | ios::out); m_nOffest = 0; compress("res/"); } else { finTable.open(RES_TABLE_FILE, ios::binary | ios::in); finData.open(ALL_RES_FILE, ios::binary | ios::in); deCompress(); } } void deCompress() { assert(finTable != 0 && finData != 0); finTable.seekg(0, ios::end); int nSize = finTable.tellg(); finTable.seekg(0, ios::beg); fstream fout; int nOffest = 0; while (nOffest < nSize) { short nFileNameLen; char * szFileName = NULL; int nFileOffest, nFileSize; char * pData = NULL; finTable.read((char *)&nFileNameLen, sizeof(short)); nOffest += sizeof(short); szFileName = (char*)malloc(nFileNameLen + 1); memset(szFileName, 0, nFileNameLen + 1); finTable.read(szFileName, nFileNameLen); nOffest += nFileNameLen; finTable.read((char *)&nFileOffest, sizeof(int)); nOffest += sizeof(int); finTable.read((char *)&nFileSize, sizeof(int)); nOffest += sizeof(int); pData = (char*)malloc(nFileSize); finData.seekg(nFileOffest, ios::beg); finData.read(pData, nFileSize); createDirectory(szFileName); fout.open(szFileName, ios::binary | ios::out); if(fout) { fout.write(pData, nFileSize); fout.close(); } if(szFileName != NULL) free(szFileName); if(pData != NULL) free(pData); } } void createDirectory(const char * filePath) { assert(filePath); int length = strlen(filePath); const int c_DirArrayLen = 512; char szDirectory[c_DirArrayLen]; const char * szPos = NULL; const char * tmp = filePath; szPos = strchr(tmp, '/'); while(szPos != NULL) { memset(szDirectory, 0, c_DirArrayLen); memcpy(szDirectory, filePath, szPos - filePath); wchar_t * wszDirectory = strToWstr(szDirectory); if (GetFileAttributes(wszDirectory) != FILE_ATTRIBUTE_DIRECTORY) CreateDirectory(wszDirectory, NULL); free(wszDirectory); tmp = szPos + 1; szPos = strchr(tmp, '/'); } } void writeToFile(char * fileName) { assert(fileName); fstream fin; fin.open(fileName, ios::binary | ios::in); if(fin) { fin.seekg(0, ios::end); int nFileSide = fin.tellg(); //先写table表 short nNameLen = strlen(fileName); //先写名字 foutTable.write((char*)&nNameLen, sizeof(short)); foutTable.write(fileName, nNameLen); //写偏移量 foutTable.write((char*)&m_nOffest, sizeof(int)); //写文件大小 foutTable.write((char*)&nFileSide, sizeof(int)); //写内容 char * szContext = (char*) malloc(nFileSide); fin.seekg(0, ios::beg); fin.read(szContext, nFileSide); foutData.write(szContext, nFileSide); free(szContext); m_nOffest += nFileSide; fin.close(); } } //遍历res文件夹中所有文件 void compress(const char* lpPath){ assert(lpPath); char szFind[100]; char szFile[100]; WIN32_FIND_DATA FindFileData; strcpy_s(szFind,lpPath); strcat_s(szFind,"*.*"); wchar_t * wszFind = strToWstr(szFind); HANDLE hFind=FindFirstFile(wszFind,&FindFileData); delete []wszFind; if (INVALID_HANDLE_VALUE == hFind) return; while(true) { if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { if (FindFileData.cFileName[0]!='.') { strcpy_s(szFile,lpPath); char * pFileName = wstrTostr(FindFileData.cFileName); strcat_s(szFile,pFileName); strcat_s(szFile,"/"); free(pFileName); compress(szFile); } } else { char * pFileName = wstrTostr(FindFileData.cFileName); char pFilePath[100] = {0}; strcpy_s(pFilePath,lpPath); //strcat_s(pFilePath,"/"); strcat_s(pFilePath,pFileName); writeToFile(pFilePath); free(pFileName); } if (!FindNextFile(hFind,&FindFileData)) break; } FindClose(hFind); } ~CFile(){ if(foutTable != 0) foutTable.close(); if(foutData != 0) foutData.close(); if(finTable != 0) finTable.close(); if(finData != 0) finData.close(); } }; ostream & green(ostream & s) { HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hstdhadle, FOREGROUND_GREEN|FOREGROUND_INTENSITY); return s; } ostream & white(ostream & s) { HANDLE hstdhadle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hstdhadle, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY); return s; } int main(int argc, char* argv[]/* f */) { //说明 if(argc >= 2 && strcmp(argv[1], "/?") == 0) { cout << green << "参数:decompress:" << "解压" << endl; cout << "restable.dat格式:" << endl << " 2byte:文件名长度n;" << endl; cout << " 'n'byte:文件名内容;" << endl; cout << " 4byte:文件的偏移位置;" << endl; cout << " 4byte:文件大小;" << white << endl; return 0; } CFile * file = new CFile(); if(argc >= 2 && strcmp(argv[1], "decompress") == 0) { file->filemode(false); delete(file);
return 0; } remove(RES_TABLE_FILE); remove(ALL_RES_FILE); file->filemode(true); delete(file);
return 0; }