在Windows下C++实现UNIX中的GZ格式的解压缩
天在做项目中遇到一个问题,项目中需要开发一个PC工具(要求是Windows),其中需要将一些文件打包成gz文件,gz文件是UNIX系统中的压缩文件,后来找了找网上的资源,只有解压的C++源码,没有告诉你如何进行GZ格式的压缩,当然了,你还可以使用7Z软件对文件进行GZ解压缩。而本篇文章将用另外一个思路去实现GZ格式的解压缩。
首先,创建一个C++的工程项目,这里使用MFC窗体项目。
功能很简单,先看下整个窗体设计:
上面一排通过“选择文件”在下面的列表中显示文件路径,然后通过“压缩”按钮,保存到指定的目录中。
下面一排通过”选择文件”选择gz格式的压缩包,然后通过“解压”按钮,保存到指定的目录中。、
界面的功能就是这样,下面我来介绍下一些主要核心的功能。
首先,来看GZ的一个处理类:
GZHelper.h 头文件
//GZ解压缩类(配合tar.exe的可执行文件)
class GZHelper
{
public:
GZHelper();
virtual ~GZHelper();
static void Compress(char* gzFilePath, int fileNum, char* file, ...); //压缩,(压缩包路径,文件个数,可变参数的文件列表)
static void Compress(char* gzFilePath, int fileNum, char** files); //压缩,(压缩包路径,文件个数,文件列表)
static void Decompress(char* folderPath, char* gzFilePath); //解压,(解压目录, 压缩包路径)private:
static CString ConvertToUnix(CString winFile); //将Window上的路径格式转换为UNIX路径格式
static void FindFile(CString path, CString outPath); //遍历目录,并将目录中的所有文件移动到outPath中
};GZHelper.cppvoid GZHelper::Compress(char* gzFilePath, int fileNum, char* file, ...)
{
va_list argptr;va_start(argptr, gzFilePath);
va_arg(argptr, int);
char** files;
files = new char*[fileNum];
for(int index = 0; index < fileNum; index++)
{
char* file = va_arg(argptr, char*);
CString str_file;
str_file = file;files[index] = new char[str_file.GetLength()];
memcpy(files[index], file, str_file.GetLength());
files[index][str_file.GetLength()] = 0;
}
va_end(argptr);Compress(gzFilePath, fileNum, files);
}void GZHelper::Compress(char* gzFilePath, int fileNum, char** files)
{
CString str_gzFilePath(gzFilePath);
CString folderPath = str_gzFilePath.Left(str_gzFilePath.ReverseFind(\) + 1);
CString command = "cd ";
command = command + Path::StartupPath() + "tar && " + Path::GetDrive() + " && tar.exe zcPf ";
CString unix_str_gzfile = ConvertToUnix(str_gzFilePath);
command = command + """ + unix_str_gzfile + "" ";
for(int index = 0; index < fileNum; index++)
{
char* file = files[index];
CString str_file;
str_file = file;
CString unix_str_file = ConvertToUnix(str_file);
command = command + """ + unix_str_file + "" ";
}
//执行命令
system(command);
}void GZHelper::Decompress(char* folderPath, char* gzFilePath)
{
CString str_folderPath(folderPath);
CString str_gzFilePath(gzFilePath);
CString command = "cd ";
command = command + Path::StartupPath() + "tar && " + Path::GetDrive() + " && tar.exe zxvf ";
CString unix_str_gzfile = ConvertToUnix(str_gzFilePath);
command = command + """ + unix_str_gzfile + "" ";system(command);
CString outPath = str_folderPath + "\demo";
CreateDirectory(outPath, NULL);CString inPath = Path::StartupPath() + "tar\cygdrive";
GZHelper::FindFile(inPath, outPath);RemoveDirectory(inPath);
}// 将Windows下的路径转换为UNIX路径
CString GZHelper::ConvertToUnix(CString winFile)
{
CString unixFile;
unixFile = winFile;
unixFile.Replace("\", "/");
unixFile = "/cygdrive/" + unixFile.Mid(0, 1) + unixFile.Mid(2, unixFile.GetLength() - 2);
return unixFile;
}void GZHelper::FindFile(CString path, CString outPath)
{
CString szDir = path + "\*.*";CFileFind fileFind;
BOOL result = fileFind.FindFile(szDir);while(result)
{
result = fileFind.FindNextFile();if(fileFind.IsDots())
continue;if(fileFind.IsDirectory())
{
GZHelper::FindFile(fileFind.GetFilePath(), outPath);
}
else
{
//移动文件
MoveFile(fileFind.GetFilePath(), outPath + "\" + fileFind.GetFileName());
}
}fileFind.Close();
}通过代码中,我们看到两个方法Compress和Decompress,这里就是作为最核心的函数。实际上,原理就是通过windows上的命令提示符cmd去调用一个tar的在Windows下编译好的一个命令包,这个包的目录内容如下:
实际上它是利用cygwin1.dll组件,将UNIX上的tar命令转换到Windows平台上运行。
这个包我会在连同工具和源码稍后在文章末尾一起奉上。
我们看到,在Compress中我们使用到"cd”命令符,这里是需要将cmd当前的路径设置到应用程序里面的一个tar包的路径上。
“&&”符号可以在单条指令中复合执行。
注意这里的command,在字符串路径中最好需要用"""将字符串隔开,这是为了防止字符串中的路径包括空格字符。
system函数执行cmd命令。
另外,我们看到ConverToUnix函数,它是用来表示将Windows下的路径转换为cygwin下的虚拟UNIX路径:
这是什么意思呢?现在我打开一个cygwin.exe工具,执行df命令:
补充:软件开发 , C++ ,