⽂件(含多级⼦⽬录)的打包和解包(下)
现在咱们说说解包,⼀个.dat⽂件,⾥⾯不知道包含了多少个⽂件/⽂件夹的信息,我们怎么解包呢?⼜怎么保证⽂件与⽂件之间、⽂件与其⼦⽂件之间的分级对应关系呢?下⾯我们来回顾⼀下打包的过程:把⽂件/⽂件夹的外部信息(⽂件名、⽂件名长度、⽂件的长度)/(⽂件夹名、⽂件夹名长度、⽂件的长度、⽂件的相对路径信息、⽂件类型)以结构体的形式存放在.dat⽂件中,内容也保存到.dat⽂件中
解包参数设置: bool UnPackFileAndDirectory(const string& inputzipfile, const string& outputpath)
其中第⼀个参数inputzipfile是要解包哪个⽂件(全路径),第⼆个参数outputpath是解包在哪⼀路径下(给定路径)
解包按照打包接⼝逻辑的话:⽂件、⽂件夹的顺序读取内容即可,当然啦,两边的结构体信息要定义相同,这样⼤家的协议就⼀样,解包便不会出现问题了。
解包流程:1.定位解包⽂件;2.解包⽂件部分(⽂件外部信息+⽂件内容),写⼊到指定路径下;3.解包⽂件夹部分(⽂件夹外部信息,没有内容哈,⽂件夹的内容为0),创建⽂件夹,并建⽴在指定路径下
1bool UnPackFileAndDirectory(const string& inputzipfile, const string& outputpath)
2 {
3 FILE *rfp = NULL;
4 rfp = fopen(inputzipfile.c_str(), "rb");
5if (rfp == NULL)
6 {
7 cout << "解包:⽂件打开失败!" << endl;
8return fal;
9 }
得的多音字10
11//⽂件部分
12int filecount;
13 fread(&filecount, sizeof(filecount), 1, rfp);
惊讶
14
15for (size_t i = 0; i < filecount; i++)
16 {
17struct FileInfo packFile;
18 fread(&packFile, sizeof(packFile), 1, rfp);
19
20 cout << "filename:" << packFile.FileName << ", nameLen:" << packFile.fileNameLen << ", fileLen:" << packFile.fileSize << endl;
21string path_file = outputpath + '\\' + packFile.FileName; //path_file:全路径
22亲情最珍贵
23 FILE *unpackFile = NULL;
24 unpackFile = fopen(path_file.c_str(), "wb");
秦国商鞅变法
25if (unpackFile == NULL)
26 {检讨书考试没考好
27 cout << "⽂件:⽂件创建失败!" << endl;
28 }
29
30 unsigned char*tmpBu = new unsigned char[packFile.fileSize];
31 fread(tmpBu, packFile.fileSize, 1, rfp);//当然也可以不借助缓冲区
32 fwrite(tmpBu, packFile.fileSize, 1, unpackFile);
33
34 }
35 cout << endl;
36
37//⽂件夹部分
38int folderCount;
39 fread(&folderCount, sizeof(folderCount), 1, rfp);
40
41for (size_t i = 0; i < folderCount; i++)
王喜兵
42 {
43struct FolderInfo folder;
44 fread(&folder, sizeof(folder), 1, rfp);
虾仁白菜饺子45
46//⽂件夹的基本信息
47 cout << "FolderName:" << folder.FolderName << ", nameLen:" << folder.FolderNameLen << ", FolderSize:" << folder.FileSize << ", path:" << folder.Filepath << ", type:" << pe << endl; 48
49string path_folder = outputpath + '\\' + folder.Filepath; //解包后全路径
念子50const char * Lpath = path_folder.c_str();
51
52if (pe == 0 ) //⽂件类型
53 {
54 FILE * unpackFolders = NULL;
55 unpackFolders = fopen(path_folder.c_str(), "wb");
56if (unpackFolders == NULL)
57 {
58 cout << "⽂件夹:⼦⽂件创建失败!" << endl;
59 }
60
61 unsigned char*readFolder = new unsigned char[folder.FileSize];
62 fread(readFolder, folder.FileSize, 1, rfp);
63 fwrite(readFolder, folder.FileSize, 1, unpackFolders);
64
65 }
66if (pe == 1)//⽂件夹类型
67 {
68 ::CreateDirectory(Lpath, NULL); //创建⽂件夹
69 }
70 }
71
72return true;
73 }
细⼼的⼩伙伴都发现了,我在⽂件解包和打包的过程中,都⽤到了临时的缓冲区:unsigned char*tmpBu = new unsigned char[fileSize];我为什么不直接从⼀个⽂件读再写⼊⽬标⽂件呢?主要是我之前就是那么⼲的,结果发现有的⽂件解包出来与原来的⽂件并不⼀致。我⽤的对⽐软件是BeyongCompare 4,这个软件是我直属领导安利的,可以对⽐两个⽂件/⽂件夹是否⼀样,⽽且任何格式的都可以,这样的软件对我来说简直就是⿊科技,amazing~
我想请教各位C++⼤神,如何不借助缓冲区,实现咱们这个功能呢?
-------------------------------------------------------------(分割线)------------------------------------------------------------------------------------------------------ 之前有位⼤神在我博⽂下评论,说我new的空间没有释放(造成内存泄漏),get到了,⼤家不要跟我⼀样粗⼼哦~
⽂件打包解包这⼀专题终于写完了,好开⼼呀。有需要改进完善的地⽅欢迎⼤家提出宝贵意见,膜拜各位⼤佬 ...