C++ zlib minizip未打包的可执行文件已损坏
我正在尝试使用miniunzip提取一些文件。它在Linux上工作。在Windows上,它不会抛出错误,但如果文件是可执行文件,则生成的二进制文件不起作用。我收到一个消息窗口,其中包含一条关于与64位Windows不兼容的消息。如果我使用另一个实用程序(如7-zip)来解包,那么一切都可以正常工作,所以问题就在我的代码中。下面是完成所有工作的类方法C++ zlib minizip未打包的可执行文件已损坏,c++,zlib,C++,Zlib,我正在尝试使用miniunzip提取一些文件。它在Linux上工作。在Windows上,它不会抛出错误,但如果文件是可执行文件,则生成的二进制文件不起作用。我收到一个消息窗口,其中包含一条关于与64位Windows不兼容的消息。如果我使用另一个实用程序(如7-zip)来解包,那么一切都可以正常工作,所以问题就在我的代码中。下面是完成所有工作的类方法 bool FileHandler::unzip( string inputFile, string outputDirectory ) {
bool FileHandler::unzip( string inputFile, string outputDirectory )
{
if (!fileExists(inputFile)) {
this->errorMessage = "Can't find file at " + inputFile;
return false;
}
unzFile zipFile = unzOpen(inputFile.c_str());
if( zipFile == nullptr ){
this->errorMessage = "FileHandler::unzip failed to open input file";
return false;
}
vector<string> files;
vector<string> folders;
unz_global_info globalInfo;
int err = unzGetGlobalInfo( zipFile, &globalInfo );
if (unzGoToFirstFile(zipFile) != UNZ_OK) {
this->errorMessage = "FileHandler::unzip failed calling unzGoToFirstFile";
return false;
}
for ( unsigned long i=0; i < globalInfo.number_entry && err == UNZ_OK; i++ ){
char filename[FILENAME_MAX];
unz_file_info subFileInfo;
err = unzGetCurrentFileInfo( zipFile, &subFileInfo, filename,
sizeof(filename), NULL, 0, NULL, 0);
if ( err == UNZ_OK )
{
char nLast = filename[subFileInfo.size_filename-1];
if ( nLast =='/' || nLast == '\\' )
{
folders.push_back(filename);
}
else
{
files.push_back(filename);
}
err = unzGoToNextFile(zipFile);
}
}
for ( string & folder : folders ){
string strippedFolder = folder.substr(0, folder.length()-1);
string dirPath = normalizePath(outputDirectory+"/"+strippedFolder);
if( ! makeDirectory( dirPath ) ){
this->errorMessage = "FileHandler::unzip Failed to create directory "+dirPath;
return false;
}
}
for ( auto it = files.begin(); it != files.end(); it++ ){
if( zipFile == 0 ){
this->errorMessage = "FileHandler::unzip invalid unzFile object at position 1";
return false;
}
string filename = *it;
//string filepath = outputDirectory + "/" + *it;
string filepath = normalizePath( outputDirectory + "/" + *it );
const char * cFile = filename.c_str();
const char * cPath = filepath.c_str();
int err = unzLocateFile( zipFile, cFile, 0 );
if ( err != UNZ_OK ){
this->errorMessage = "FileHandler::unzip error locating sub-file.";
return false;
}
err = unzOpenCurrentFile( zipFile );
if( err != UNZ_OK ){
this->errorMessage = "FileHandler::unzip error opening current file";
return false;
}
ofstream fileStream{ cPath };
// Need an ostream object here.
if( fileStream.fail() ){
this->errorMessage = "FileHandler::unzip error opening file stream at "+string(cPath);
return false;
}
unz_file_info curFileInfo;
err = unzGetCurrentFileInfo( zipFile, &curFileInfo, 0, 0, 0, 0, 0, 0);
if ( err != UNZ_OK )
{
this->errorMessage = "FileHandler::unzip failed to read size of file";
return false;
}
unsigned int size = (unsigned int)curFileInfo.uncompressed_size;
char * buf = new char[size];
size = unzReadCurrentFile( zipFile, buf, size );
if ( size < 0 ){
this->errorMessage = "FileHandler::unzip unzReadCurrentFile returned an error. ";
return false;
}
fileStream.write( buf, size );
fileStream.flush();
delete [] buf;
fileStream.close();
#ifndef _WIN32
vector<string> parts = splitString(filename, ".");
if( parts.size() == 1 ){ // In linux, assume file without extension is executable
mode_t old_mask = umask( 000 );
chmod( cPath, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH );
umask( old_mask );
}
#endif
unzCloseCurrentFile( zipFile );
}
unzClose(zipFile);
return true;
}
bool FileHandler::解压(字符串输入文件,字符串输出目录)
{
如果(!fileExists(inputFile)){
此->errorMessage=“无法在“+inputFile”处找到文件;
返回false;
}
unzFile-zipFile=unzOpen(inputFile.c_str());
if(zipFile==nullptr){
此->errorMessage=“FileHandler::unzip无法打开输入文件”;
返回false;
}
矢量文件;
矢量文件夹;
全球信息全球信息;
int err=unzGetGlobalInfo(zipFile和globalInfo);
如果(unzGoToFirstFile(zipFile)!=UNZ_确定){
此->errorMessage=“FileHandler::unzip调用unzGoToFirstFile失败”;
返回false;
}
for(无符号长i=0;ierrorMessage=“FileHandler::unzip未能创建目录”+dirPath;
返回false;
}
}
对于(自动it=files.begin();it!=files.end();it++){
如果(zipFile==0){
此->errorMessage=“FileHandler::解压位置1处的无效解压文件对象”;
返回false;
}
字符串文件名=*它;
//字符串filepath=outputDirectory+“/”++*it;
字符串filepath=normalizePath(outputDirectory+“/”+*it);
const char*cFile=filename.c_str();
const char*cPath=filepath.c_str();
int err=unzLocateFile(zipFile,cFile,0);
如果(错误!=UNZ_OK){
此->errorMessage=“FileHandler::解压查找子文件时出错。”;
返回false;
}
err=unzOpenCurrentFile(zipFile);
如果(错误!=UNZ_OK){
此->errorMessage=“FileHandler::解压打开当前文件时出错”;
返回false;
}
流文件流{cPath};
//这里需要一个ostream对象。
if(fileStream.fail()){
这->errorMessage=“FileHandler::在“+字符串(cPath)”处打开文件流时发生解压缩错误;
返回false;
}
unz_file_info curFileInfo;
err=unzGetCurrentFileInfo(zipFile和curFileInfo,0,0,0,0,0);
如果(错误!=UNZ_OK)
{
此->errorMessage=“FileHandler::unzip无法读取文件大小”;
返回false;
}
unsigned int size=(unsigned int)curFileInfo.uncompressed_size;
char*buf=新字符[大小];
size=unzReadCurrentFile(zipFile,buf,size);
如果(尺寸<0){
此->errorMessage=“FileHandler::解压unzReadCurrentFile返回错误。”;
返回false;
}
写入(buf,大小);
flush();
删除[]buf;
fileStream.close();
#ifndef\u WIN32
向量部分=拆分字符串(文件名“.”);
在linux中,如果(parts.size()==1){//,则假定不带扩展名的文件是可执行文件
模式旧掩码=umask(000);
chmod(cPath,S|u IRWXU | S|u IRWXG | S|u IROTH | S|IXOTH);
umask(旧_面具);
}
#恩迪夫
unzCloseCurrentFile(zipFile);
}
unzClose(zipFile);
返回true;
}
std::ostream
默认情况下以文本模式打开文件,您需要将其改为使用二进制模式
在Linux上,文本模式和二进制模式之间似乎没有任何区别。但在Windows上,尝试将\n
写入文本文件会产生\r\n
,从而使数据中断
你需要换一行
ofstream fileStream{ cPath };
到
std::ostream
默认情况下以文本模式打开文件,您需要将其改为使用二进制模式
在Linux上,文本模式和二进制模式之间似乎没有任何区别。但在Windows上,尝试将\n
写入文本文件会产生\r\n
,从而使数据中断
你需要换一行
ofstream fileStream{ cPath };
到
我的水晶球说这是因为默认情况下,
std::ostream
使用文本模式,而不是二进制模式。@HolyBlackCat。就这样。谢谢如果你提交你的评论作为回答,我会接受。很高兴它奏效了!答案是这样的。我的水晶球说这是因为默认情况下,std::ostream
使用文本模式,而不是二进制模式。@HolyBlackCat。就这样。谢谢如果你提交你的评论作为回答,我会接受。很高兴它奏效了!答案是这样的。