日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

在Windows下C++实现UNIX中的GZ格式的解压缩(附工具)

發(fā)布時間:2023/12/31 综合教程 43 生活家
生活随笔 收集整理的這篇文章主要介紹了 在Windows下C++实现UNIX中的GZ格式的解压缩(附工具) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天在做項目中遇到一個問題,項目中需要開發(fā)一個PC工具(要求是Windows),其中需要將一些文件打包成gz文件,gz文件是UNIX系統(tǒng)中的壓縮文件,后來找了找網(wǎng)上的資源,只有解壓的C++源碼,沒有告訴你如何進(jìn)行GZ格式的壓縮,當(dāng)然了,你還可以使用7Z軟件對文件進(jìn)行GZ解壓縮。而本篇文章將用另外一個思路去實現(xiàn)GZ格式的解壓縮。

首先,創(chuàng)建一個C++的工程項目,這里使用MFC窗體項目。

功能很簡單,先看下整個窗體設(shè)計:

上面一排通過“選擇文件”在下面的列表中顯示文件路徑,然后通過“壓縮”按鈕,保存到指定的目錄中。

下面一排通過”選擇文件”選擇gz格式的壓縮包,然后通過“解壓”按鈕,保存到指定的目錄中。、

界面的功能就是這樣,下面我來介紹下一些主要核心的功能。

首先,來看GZ的一個處理類:

GZHelper.h 頭文件

//GZ解壓縮類(配合tar.exe的可執(zhí)行文件)
class GZHelper
{
public:
	GZHelper();
	virtual ~GZHelper();
	static void Compress(char* gzFilePath, int fileNum, char* file, ...); //壓縮,(壓縮包路徑,文件個數(shù),可變參數(shù)的文件列表)
	static void Compress(char* gzFilePath, int fileNum, char** files); //壓縮,(壓縮包路徑,文件個數(shù),文件列表)
	static void Decompress(char* folderPath, char* gzFilePath); //解壓,(解壓目錄, 壓縮包路徑)

private:
	static CString ConvertToUnix(CString winFile); //將Window上的路徑格式轉(zhuǎn)換為UNIX路徑格式
	static void FindFile(CString path, CString outPath); //遍歷目錄,并將目錄中的所有文件移動到outPath中
};

GZHelper.cpp

void 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 + "\" ";
	}
	
	//執(zhí)行命令
	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下的路徑轉(zhuǎn)換為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,這里就是作為最核心的函數(shù)。

實際上,原理就是通過windows上的命令提示符cmd去調(diào)用一個tar的在Windows下編譯好的一個命令包,這個包的目錄內(nèi)容如下:

實際上它是利用cygwin1.dll組件,將UNIX上的tar命令轉(zhuǎn)換到Windows平臺上運行。

這個包我會在連同工具和源碼稍后在文章末尾一起奉上。

我們看到,在Compress中我們使用到"cd”命令符,這里是需要將cmd當(dāng)前的路徑設(shè)置到應(yīng)用程序里面的一個tar包的路徑上。

“&&”符號可以在單條指令中復(fù)合執(zhí)行。

注意這里的command,在字符串路徑中最好需要用"\""將字符串隔開,這是為了防止字符串中的路徑包括空格字符

system函數(shù)執(zhí)行cmd命令。

另外,我們看到ConverToUnix函數(shù),它是用來表示將Windows下的路徑轉(zhuǎn)換為cygwin下的虛擬UNIX路徑:

這是什么意思呢?現(xiàn)在我打開一個cygwin.exe工具,執(zhí)行df命令:

可以看到,每個磁盤上的路徑都已經(jīng)對應(yīng)了在cygwin中特定的虛擬路徑,如D: 對應(yīng) /cygdrive/d

ConverToUnix方法就是要將磁盤上的路徑轉(zhuǎn)換為cygwin可識別的虛擬路徑下面。

在tar.exe中對簡單的壓縮以及解壓的指令,具體可以參考:http://www.21andy.com/blog/20060820/389.html

大家也許注意到:static void Compress(char* gzFilePath, int fileNum, char* file, ...);

這種寫法很有趣,這個表示是一個可變形參的方法。后面“…”號,可以有任意個的參數(shù)表示,這樣做的目的,是為了可以對任意多個文件進(jìn)行壓縮。在方法中,通過va_list,va_start,va_arg,va_end,va_list作為一個參數(shù)的指針通過va_arg可以移動指針到下一個參數(shù)中,從而遍歷可變參數(shù)的值。

另外,我在工具中添加了一個目錄選擇的類:

頭文件:

//目錄選擇類
class CFolderDialog
{
public:
	CFolderDialog(
		LPCTSTR title, 
		DWORD dwFlags = BIF_STATUSTEXT | BIF_USENEWUI | BIF_RETURNONLYFSDIRS);
	virtual ~CFolderDialog();

	virtual INT_PTR DoModal(HWND hwnd);
	CString GetPathName() const;

private:
	BROWSEINFO browseInfo;
	CString m_path;
};

cpp文件:

/* CFolderDialog Begin */
CFolderDialog::CFolderDialog(LPCTSTR title, DWORD dwFlags)
{
	char szDir[MAX_PATH];

    ITEMIDLIST *pidl;
    //
    
    browseInfo.lpszTitle = title;
    browseInfo.ulFlags = dwFlags;
    
}

CFolderDialog::~CFolderDialog()
{

}

INT_PTR CFolderDialog::DoModal(HWND hwnd)
{
	char szDir[MAX_PATH];
	ITEMIDLIST *pidl;
	browseInfo.pidlRoot = NULL;
    browseInfo.pszDisplayName = szDir;
	browseInfo.hwndOwner = hwnd;

	browseInfo.lpfn = NULL;
    browseInfo.lParam = 0;
    browseInfo.iImage = 0;
    pidl = SHBrowseForFolder(&browseInfo);
    if(pidl == NULL)  
		return 2;
    if(!SHGetPathFromIDList(pidl, szDir))	
		return 2;

	m_path = szDir;
	return 1;
}

CString CFolderDialog::GetPathName() const
{
	return m_path;
}

/* CFolderDialog End */

如何調(diào)用:

CFolderDialog folderDialog("壓縮到目錄:");

int result = folderDialog.DoModal(this->m_hWnd);

if(result == 1)
{
    ...
}

最后附上該工具的源代碼(內(nèi)含tar命令包):GZCompressDemo.rar

希望對大家有所幫助!

總結(jié)

以上是生活随笔為你收集整理的在Windows下C++实现UNIX中的GZ格式的解压缩(附工具)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。