#include "stdafx.h"
#include "iostream"
#include "fstream"
#include <string.h>
using std::fstream;
using std::ios;
using std::string;
struct index
{
size_t offset;//文件偏移量
size_t FillSize;//文件大小
size_t namelength;//文件名长度
char *pName;//文件名
};
//打包
void packFile(char* fileName[], size_t fillNum){
size_t fillTableSize = 0;//文件索引表大小
fstream srcFile;
fillTableSize += 4;//保存索引表大小
fillTableSize += 4;//保存文件数目
index *pFillDate = new index[fillNum];
for (size_t i = 0; i < fillNum; i++)
{
//得到所有图片的偏移量
if (i>0)
{
(pFillDate + i)->offset = (pFillDate + i - 1)->offset + (pFillDate + i - 1)->FillSize;
}
else
{
(pFillDate + i)->offset = 0;//i == 0,偏移量为0
}
fillTableSize += 4;
//得到所有图片的大小
srcFile.open(fileName[i], ios::in | ios::binary);
srcFile.seekp(0, ios::end);
(pFillDate + i)->FillSize = (size_t)srcFile.tellp();
srcFile.close();
fillTableSize += 4;
//得到所有文件名长度
(pFillDate + i)->namelength = strlen(fileName[i]);
fillTableSize += 4;
//得到所有文件名
(pFillDate + i)->pName = new char[(pFillDate + i)->namelength + 1];
strcpy_s((pFillDate + i)->pName, (pFillDate + i)->namelength + 1, fileName[i]);
fillTableSize += (pFillDate + i)->namelength;
}
fstream destFile;//目标文件,最后打包的文件
//写入文件打包
destFile.open("ImageFill.pak", ios::out | ios::binary);
destFile.write((char*)&fillTableSize, sizeof(size_t));//先写入文件索引表的大小
destFile.write((char*)&fillNum, sizeof(size_t));//再写入文件数目
//写入索引表的内容
for (size_t i = 0; i < fillNum; i++)
{
destFile.write((char*)&(pFillDate + i)->offset, sizeof(size_t));
destFile.write((char*)&(pFillDate + i)->FillSize, sizeof(size_t));
destFile.write((char*)&(pFillDate + i)->namelength, sizeof(size_t));
destFile.write((pFillDate + i)->pName, sizeof(char)*(pFillDate + i)->namelength);
}
//再接下来一个一个文件往后写入
for (size_t i = 0; i < fillNum; i++)
{
srcFile.open((pFillDate + i)->pName, ios::in | ios::binary);
for (size_t j = 0; j < (pFillDate + i)->FillSize; j++)
{
destFile.put(srcFile.get());
}
srcFile.close();
}
destFile.close();
for (size_t i = 0; i < fillNum; i++)
delete[](pFillDate + i)->pName;
delete[]pFillDate;
}
//解包
void breakFile(){
fstream srcFile;
fstream destFile;
srcFile.open("ImageFill.pak", ios::in | ios::binary);
//解压索引表
size_t fillTableSize = 0;
srcFile.read((char*)&fillTableSize, sizeof(size_t));
size_t fillNum = 0;
srcFile.read((char*)&fillNum, sizeof(size_t));
index *pFillDate = new index[fillNum];
for (size_t i = 0; i < fillNum; i++)
{
srcFile.read((char*)&(pFillDate + i)->offset, sizeof(size_t));
srcFile.read((char*)&(pFillDate + i)->FillSize, sizeof(size_t));
srcFile.read((char*)&(pFillDate + i)->namelength, sizeof(size_t));
(pFillDate + i)->pName = new char[(pFillDate + i)->namelength + 1];
memset((pFillDate + i)->pName, 0, sizeof(char)*((pFillDate + i)->namelength + 1));
srcFile.read((pFillDate + i)->pName, sizeof(char)*(pFillDate + i)->namelength);
}
//解压图片文件
for (size_t i = 0; i < fillNum; i++)
{
char tempName[128] = {};
strcpy_s(tempName, "abc");
strcat_s(tempName, (pFillDate + i)->pName);//每个解包图片文件名连接abc
destFile.open(tempName, ios::out | ios::binary);
srcFile.seekp(fillTableSize + (pFillDate + i)->offset, SEEK_SET);
for (size_t j = 0; j < (pFillDate + i)->FillSize; j++)
{
destFile.put(srcFile.get());
}
destFile.close();
}
for (size_t i = 0; i < fillNum; i++)
delete[](pFillDate + i)->pName;
delete[]pFillDate;
srcFile.close();
}