之前寫過一篇用zlib庫來壓縮的,但zlib只能壓縮文件,我需要壓縮文件夾,要想壓縮文件夾還得利用zlib庫自己寫代碼,我是真的服了,一個開源庫這么不好用。
C++復制文件夾也是麻煩事,網上這篇文章:http://blog.csdn.net/u012750702/article/details/52738859 實現了文件夾復制,但是不能包含子目錄的。暫時夠我用了。他這個寫的也沒啥技術含量,就是查找到文件夾下所有文件名,組成目錄,然后一個個復制過去。
另外,這篇文章的代碼不能實現復制包含子目錄文件夾的功能,其實,這個功能很好實現。
只需要查詢目錄下所有文件名的函數改寫一下,實現查詢目錄下所有文件相對路徑(而非文件名),子目錄則遞歸查詢。參數std::vector<std::string> file_paths用於存儲所有文件相對路徑。之后再一個一個復制過去就好了。
之前在網上看過實現查詢一個目錄下(包含子目錄)所有文件路徑的功能的函數(下面函數是64位環境的,32位的把對應函數名換成32位的即可):
/* ** 作者:sonne ** 日期:2017-06-12 ** 說明:讀取制定目錄下所有文件路徑和文件名 */ void getFileNamesAndPaths(string path, vector<string>& files, vector<string>& file_name) { //文件句柄 __int64 hFile = 0; //文件信息,聲明一個存儲文件信息的結構體 //struct _finddata_t fileinfo; struct __finddata64_t fileinfo; //字符串,存放路徑 string p; if ((hFile = _findfirst64(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)//若查找成功,則進入 { do { //如果是目錄,迭代之 if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) getFileNamesAndPaths(p.assign(path).append("\\").append(fileinfo.name), files, file_name); } //如果不是,加入列表 else { files.push_back(p.assign(path).append("\\").append(fileinfo.name)); file_name.push_back(fileinfo.name); } } while (_findnext64(hFile, &fileinfo) == 0); //_findclose函數結束查找 _findclose(hFile); } }
其實C++17,帶的庫就支持文件夾復制。如果你用英文google搜索一下,就能找到相關文章https://stackoverflow.com/questions/37325875/copy-directory-content,用百度,呵呵了,就只能搜到上述的那類文章。
壓縮文件夾的話,比復制文件夾更麻煩,我暫時沒精力去深入研究什么zlib。
最后我想的辦法就是使用bat腳本。
用bat運行命令,運行winrar去壓縮指定目錄文件夾到目標文件。
我的寫法:
@echo off Color a9 "D:\test\winrar\WinRAR.exe" a D:\test\目標文件.rar D:\test\源文件夾 Pause
上面使用的是絕對路徑,我做的項目由於winrar和要壓縮的目錄都在項目目錄所以需要相對路徑:
@echo off Color a9 cd /d %~dp0 "winrar\WinRAR.exe" a back_up.rar cp_dir Pause
主要是cd /d %~dp0這句,表示到當前路徑操作。
C程序里運行這個腳本只需這樣寫:
#include <windows.h> void main() { WinExec("D:\\test\\zzz.bat", SW_HIDE); }
這樣做缺點是你必須知道winrar程序路徑,或者winrar路徑要寫在系統環境變量里。
最后我覺得就把winrara程序放在項目目錄里好了,反正也不大。
但WinExec只能在32位下使用,64位需要使用ShellExecute。
ShellExecute(NULL,"open","the path",NULL,NULL,SW_SHOWNORMAL);