ZIP流对象的使用(如何压缩生成ZIP文件和解压缩ZIP文件)
使用环境: wxWidgets 3.0.4, CodeBlock17.12
#include <wx/wfstream.h>
#include <wx/zstream.h>
#include <wx/filename.h>
#include <wx/zipstrm.h>
#include <wx/txtstrm.h>
wxZipInputStream是一个比较复杂的流对象,因为它是以文档的方式工作,而不是线性的二进制数据的方式工作。事实上,文档是通过另外的类wxArchiveClassFactory和wxArchiveEntry来处理的, 当然你可以不用关心这些细节。使用 wxZipInputStream类,你可以有两种构造方法,一种是直接使用一个指向zip文件的文件流对象,另外一种方法则是通过一个zip文件路径和一个zip文件中文档的路径来指定一个zip数据流。
下面的例子演示了这两种方法:
// 方法一: 以两步方式创建zip输入流.
wxZipEntry* entry;
wxFFileInputStream in(wxT("test.zip"));
wxZipInputStream zip(in);
wxTextInputStream txt(zip);
wxString data;
while (entry = zip.GetNextEntry())
{
wxString name = entry->GetName(); //访问元数据
txt >> data; //读取数据
delete entry;
}
// 方法二: 直接指定源文档路径和内部文件路径。
wxZipInputStream in(wxT("test.zip"), wxT("text.txt"));
wxTextInputStream txt(zip);
wxString data;
txt >> data; //读取数据
wxZipOutputStream用来写zip压缩文件。 先用PutNextEntry 或PutNextDirEntry 函数用来在压缩文件中创建一个新的文件(目录), 然后就可以写相应的数据了。
例如:
wxFFileOutputStream out(wxT("test.zip"));
wxZipOutputStream zip(out);
wxTextOutputStream txt(zip);
zip.PutNextEntry(wxT("entry1.txt"));
txt << ( wxT("Some text for entry1\n") );
zip.PutNextEntry(wxT("entry2.txt"));
txt << ( wxT("Some text for entry2\n") );
如何压缩打包生成ZIP文件
下面代码用于将多个文件压缩打包为一个ZIP文件。
bool CompressZipFile(const wxArrayString& inFiles,const wxString& aZipFile)
{//compress all files in inFiles to aZipFile //将字符串队列中的所有文件,压缩为一个ZIP格式的文件,zip文件名为aZipFile,如果zZipFile不包括目录名,默认是保存在当前目录。
wxFFileOutputStream out(aZipFile);
wxZipOutputStream zip(out);
for(size_t i=0;i<inFiles.GetCount();i++){
wxString fullname=inFiles[i];
if(wxFileName::FileExists(fullname))
{
wxFileName fname(fullname);//
wxString strname = fname.GetFullName();//filename and exetension
zip.PutNextEntry(strname);
// Read from the specified file
wxFileInputStream FileInputStream(fullname);
zip.Write(FileInputStream);
}
}
return true;
}
使用该函数的方法如下:
//压缩文件, 将test1.txt和test2.txt,打包压缩为一个temp00.zip。
wxArrayString files;
files.Add(_T(“test1.txt”));files.Add(_T(“test2.txt”));
CompressZipFile(m_sndFilenames,_T("temp00.zip"));
解压缩ZIP文件
下面代码用于将一个ZIP文件解压缩到指定目录。
bool ExtractZipFiles(const wxString& aZipFile, const wxString& aTargetDir)
{//将aZipFile压缩格式为zip的文件,解压缩到aTargetDir这个目录,如果是当前目录aTargetDir="."
wxString PathSeparator=wxFileName::GetPathSeparator();
wxString TargetDir;
if (aTargetDir.substr(aTargetDir.Length()-1,1) != PathSeparator)
TargetDir=aTargetDir + PathSeparator;
else
TargetDir=aTargetDir;
wxFileInputStream in(aZipFile);
if (!in) {
wxLogError(wxT("open ZIP FILE") + aZipFile + wxT("ERROR!"));
return false;
}
wxZipInputStream zip(in);
wxZipEntry* entry=zip.GetNextEntry();
while (entry != NULL)
{
wxString name=entry->GetName();
wxFileName fname(name);
wxString FilePath=fname.GetPath();
if (!wxFileName::DirExists(TargetDir + FilePath))
wxFileName::Mkdir(TargetDir + FilePath,wxS_DIR_DEFAULT,wxPATH_MKDIR_FULL);
wxFileOutputStream file(TargetDir + name);
if (!file) {
wxLogError(wxT("CREATE OUTPUT FILE") + TargetDir + name + wxT("ERROR !"));
return false;
}
zip.Read(file);
delete entry;
entry=zip.GetNextEntry();
}
return true;
}
解压缩的使用方法如下:
//解压文件
wxString aZipFile=_T("temp00.zip");
wxString aTargetDir = _T(".");//当前文件夹
ExtractZipFiles(aZipFile,aTargetDir);