文件的打包和解包(简单的无加密)

来源:互联网 发布:青少年安全上网软件 编辑:程序博客网 时间:2024/06/06 16:32
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
struct Pk
{
int Offest;//每个文件的偏移量
int FileLen;//文件长度
int FileNameLen;//文件名长度
char* FileName;//需要打包的文件名
};
class Package
{
public:
Package(const char* Fname, int concordancesize, int FileNum) :Fname(Fname), concordancesize(concordancesize),FileNum(FileNum){}//创建文件名
~Package()
{
delete[]concordance;
}
void Packaging(const char* Fnamenamew[], int num);//打包
void UnPack(const char* name);//解包
protected:
private:
Pk* concordance;
fstream file;
int concordancesize;//索引表大小
int FileNum;//文件个数
const char* Fname;//打包完成后的文件名
};
void Package::Packaging(const char* Fnamenamew[], int num)//打包
{
int m = 0;
FileNum = num;//文件个数
concordance = new Pk[num];//结构体数组
for (int i = 0; i < num; ++i)
{
if (i == 0)//得到每个文件的偏移位置
{
concordance[i].Offest = 0;
}
else
{
concordance[i].Offest = concordance[i - 1].Offest + concordance[i - 1].FileLen;
}
m = m + strlen(Fnamenamew[i]) +1+ 3 * sizeof(int);//算索引表大小
concordance[i].FileNameLen = strlen(Fnamenamew[i])+1;//文件名大小
file.open(Fnamenamew[i], ios::in | ios::binary);
file.seekg(0, ios::end);
concordance[i].FileLen = file.tellg();//获取每个文件的大小
file.seekg(0, ios::beg);
file.close();
}
concordancesize = m + 2 * sizeof(int);//得到索引表大小
file.open(Fname, ios::out | ios::binary);
file.write((char*)&concordancesize, sizeof(int));
file.write((char*)&FileNum, sizeof(int));
for (int i = 0; i < num; ++i)
{
file.write((char*)&concordance[i].Offest, sizeof(int));//写入每个文件的偏移量
file.write((char*)&concordance[i].FileLen, sizeof(int));//写入每个文件的大小
file.write((char*)&concordance[i].FileNameLen, sizeof(int));//写入每个文件名的大小
file.write(Fnamenamew[i], concordance[i].FileNameLen);//写入每个文件的文件名
}
fstream file1;
for (int i = 0; i < num; ++i)//最后写入文件
{
file1.open(Fnamenamew[i], ios::in | ios::binary);
for (int j = 0; j < concordance[i].FileLen; ++j)
{
file.put(file1.get());
}
file1.close();
}
file.close();
}
void Package::UnPack(const char *name)//解包
{
file.open(name, ios::in | ios::binary);
file.read((char*)&concordancesize, sizeof(int));//读取索引表大小
file.read((char*)&FileNum, sizeof(int));//读取文件个数
file.seekg(8, ios::beg);
concordance = new Pk[FileNum];
for (int i = 0; i < FileNum; ++i)//读取索引表具体的内容
{
file.read((char*)&concordance[i].Offest, sizeof(int));//读取偏移量
file.read((char*)&concordance[i].FileLen, sizeof(int));//读取文件大小
file.read((char*)&concordance[i].FileNameLen, sizeof(int));//读取文件名大小
concordance[i].FileName = new char[concordance[i].FileNameLen];
memset(concordance[i].FileName, 0, sizeof(char)*concordance[i].FileNameLen);//设置为零
file.read(concordance[i].FileName,concordance[i].FileNameLen);//读取文件名
}
fstream file1;
for (int i=0; i < FileNum; ++i)
{
char arr[1024] = {0};
sprintf(arr,"map\\%s" ,concordance[i].FileName);//另存在文件夹map中
file1.open(arr, ios::out | ios::binary);
file.seekg(concordancesize + concordance[i].Offest, ios::beg);//打开文件
for (int j = 0; j < concordance[i].FileLen; ++j)//copy文件
{
file1.put(file.get());
}
file1.close();
}
file.close();
for (int i = 0; i < FileNum; ++i)//释放内存
{
delete[]concordance[i].FileName;
}
}
int main()
{
Package a("156.txt",0,0);
const char *name[2] = { "789.png", "678.jpg" };
a.Packaging(name, 2);
a.UnPack("156.txt");
system("pause");
return 0;
}
原创粉丝点击