⽂件(含多级⼦⽬录)的打包和解包(下)
  现在咱们说说解包,⼀个.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 false;
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        }
29fread和fwrite的区别
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到了,⼤家不要跟我⼀样粗⼼哦~
  ⽂件打包解包这⼀专题终于写完了,好开⼼呀。有需要改进完善的地⽅欢迎⼤家提出宝贵意见,膜拜各位⼤佬 ...