欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++實現(xiàn)解析zip文件的示例代碼

 更新時間:2023年12月08日 14:00:30   作者:spirits_of_snail  
這篇文章主要為大家詳細介紹了如何利用c++實現(xiàn)解析zip文件,并對流式文件pptx內(nèi)容的修改,文中的示例代碼講解詳細,有需要的小伙伴可以參考一下

libzip

官網(wǎng)地址:

示例代碼

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <zip.h>

//解析原始zip內(nèi)容,保存為新的zip文件
int ziptest(const char* inputPath, const char* outputPath)
{
	int error = 0;
	zip_t *zip_file = zip_open(inputPath, ZIP_CHECKCONS, &error);
	if (zip_file == NULL) {
		printf("Failed to open zip file: %s\n", zip_strerror(zip_file));
		return 1;
	}

	// 獲取條目數(shù)量
	int numEntries = zip_get_num_entries(zip_file, 0);
	if (numEntries < 0) {
		std::cerr << "Failed to get number of entries." << std::endl;
		zip_close(zip_file);
		return 1;
	}

	//保存為目標(biāo)zip文件
	zip_t* archive = zip_open(outputPath, ZIP_CREATE | ZIP_TRUNCATE, nullptr);
	if (archive == nullptr) {
		std::cout << "無法創(chuàng)建 ZIP 存檔." << std::endl;
		return 1;
	}
	unsigned char* itemData = NULL;
	for (size_t i = 0; i < numEntries; i++) {
		zip_stat_t entryStat;
		if (zip_stat_index(zip_file, i, 0, &entryStat) != 0) {
			std::cerr << "Failed to get information for entry " << i << std::endl;
			continue;
		}
		//printf("index: [%llu]\t", entryStat.index);
		//printf("Name: [%s]\t", entryStat.name);
		//printf("valid: [%llu]\t", entryStat.valid);
		//printf("Size: [%llu]\t", entryStat.size);
		//printf("comp_size: [%llu]\t", entryStat.comp_size);
		//printf("comp_method: [%zu]", entryStat.comp_method);
		//printf("\t flags: [%lu]\n", entryStat.flags);
		if (entryStat.valid & ZIP_STAT_NAME) {
			// 打開條目文件
			zip_file_t *entryFile = zip_fopen_index(zip_file, i, 0);
			if (entryFile == NULL) {
				std::cerr << "Failed to open entry file: " << entryStat.name << std::endl;
				//goto END;
				continue;
			}
			size_t bufferSize = entryStat.size;
			// 讀取內(nèi)存空間
			itemData = (unsigned char *)malloc(bufferSize);
			if (zip_fread(entryFile, itemData, bufferSize) < 0) {
				std::cerr << "Failed to read entry file: " << entryStat.name << std::endl;
				zip_fclose(entryFile);
				if (itemData != NULL) {
					free(itemData);
					itemData = NULL;
				}
				continue;
			}

			// 創(chuàng)建源對象,并將其添加到 ZIP 存檔中
			//zip_source_buffer內(nèi)部會自動釋放itemData內(nèi)存
			zip_source* source = zip_source_buffer(archive, itemData, bufferSize, 0);
			if (source == NULL) {
				std::cout << "無法寫入 ZIP 文件." << std::endl;
				if (itemData != NULL) {
					free(itemData);
					itemData = NULL;
				}
				zip_fclose(entryFile);
				continue;
			}
			//  use zip_file_replace() to modify source zip file
			/****
			if (zip_file_replace(zip_file, i, source, 0) < 0) {
				std::cout << "replace failed." << std::endl;
				zip_source_free(source);
				zip_fclose(entryFile);
				break;
			}
			****/

			if (zip_file_add(archive, entryStat.name, source, ZIP_FL_OVERWRITE) < 0) {
				std::cout << "無法寫入 ZIP 文件." << std::endl;
				zip_source_free(source);
				zip_fclose(entryFile);
				if (itemData != NULL) {
					free(itemData);
					itemData = NULL;
				}
				continue;
			}
			zip_fclose(entryFile);
		}
	}
	// 關(guān)閉zip文件
	zip_close(zip_file);
	zip_close(archive);
	return 0;
}
#include <zip.h>
#include <memory.h>
#include <stdio.h>
#include <math.h>
#include <fstream>

#ifdef _WIN32
#include <io.h> /* _access */
#include<direct.h> /* _mkdir */
#include<windows.h>
#else
#include<unistd.h> /* access */
#include<sys/stat.h> /*mkdir*/
#include <sys/types.h>
#endif 

//創(chuàng)建多級文件夾
void createFolders(std::string rootPath);
//獲取多級文件夾下所以文件列表
void getDirAllFilePath(const char* folderPath, std::vector<std::string>& filePaths);

//解壓zip,保存到磁盤指定目錄
int unzipFunc(const char* destzip, const std::string output) {
	// 打開ZIP文件
	zip* archive = zip_open(destzip , 0, NULL);
	if (!archive) {
		std::cerr << "Failed to open archive" << std::endl;
		return -1;
	}
	// 獲取ZIP文件中的文件數(shù)量
	int numFiles = zip_get_num_files(archive);
	//std::cout << "Archive contains " << numFiles << " files" << std::endl;

	// 遍歷ZIP文件中的所有文件
	for (int i = 0; i < numFiles; ++i) {
		FILE *fp = NULL;
		// 獲取文件的名稱和大小
		zip_stat_t fileStat;
		zip_stat_init(&fileStat);
		if (zip_stat_index(archive, i, 0, &fileStat) != 0) {
			std::cerr << "Failed to get file info for index " << i << std::endl;
			continue;
		}

		int len = strlen(fileStat.name);
		std::cout << "File " << i << ": " << fileStat.name << " (" << fileStat.size << " bytes)" << std::endl;

		// 解壓文件到磁盤指定位置, 執(zhí)行解壓之前, 需創(chuàng)建對應(yīng)的文件夾,否則,解壓失敗
		std::string dest_name = output + std::string(fileStat.name);
		createFolders(dest_name);
		
		zip_file_t* zf = zip_fopen_index(archive, i, 0);
		if (!zf) { 
			continue; 
		}
		fp = fopen(dest_name.c_str(), "wb");
		if (fp == NULL) { continue; }
		long long sum = 0;
		unsigned char* buffer = (unsigned char*)malloc(fileStat.size);

		memset(buffer, 0, fileStat.size);
		if (zip_fread(zf, buffer, fileStat.size) < 0) {
			continue;
		}
		fwrite(buffer, 1, fileStat.size, fp);
		free(buffer);
		buffer = NULL;
		
		zip_fclose(zf);
		fclose(fp);
	}
	
	// 關(guān)閉ZIP文件
	if (zip_close(archive) != 0) {
		std::cerr << "Failed to close archive" << std::endl;
		return -1;
	}
	return 0;
}


//將文件夾壓縮為指定的zip
int zipFunc(const char* inputDirPath, const char* destzip) {
	// 打開ZIP文件
	int iErr = 0;
	zip* archive = zip_open(destzip, ZIP_CREATE | ZIP_TRUNCATE, &iErr);
	if (!archive) {
		std::cerr << "Failed to open archive" << std::endl;
		return -1;
	}

	std::vector<std::string> files;
	//獲取的是絕對路徑
	getDirAllFilePath(inputDirPath, files);
	
	std::string rootPath(inputDirPath);
	for (size_t i = 0; i < files.size(); i++) {
		
		std::string::size_type rootSize = rootPath.length();
		//獲取指定目錄下的相對路徑,作為zip包的條目名稱
		std::string itemName = files[i].substr(rootSize + 1);
		std::cout << "entry: " << files[i].c_str() << std::endl;
		//通過文件創(chuàng)建zip_source源對象
		zip_source_t* source = zip_source_file(archive, files[i].c_str(), 0, -1);
		if (!source)
		{
			printf(" open zip_source file failed\n");
			zip_close(archive);
			return 1;
		}
		//add file
		if (zip_file_add(archive, itemName .c_str(), source, ZIP_FL_OVERWRITE) < 0) {
			zip_source_free(source);
			zip_close(archive);
			return 2;
		}
	}
	// 關(guān)閉ZIP文件
	if (zip_close(archive) != 0) {
		std::cerr << "Failed to close archive" << std::endl;
		return -1;
	}
	return 0;
}

//創(chuàng)建文件夾
int create_dir(const char *dir)
{
#ifdef WIN32
	if ((_access(dir, 0)) != 0)	//如果文件夾不存在
	{
		int flag = _mkdir(dir);
		if (flag != 0)
		{
			printf("Fail to create directory %s.", dir); //"Fail to create directory." << std::endl;
			return OOXML_PARAMETER_ERR;
		}
	}
#else
	if ((access(dir, 0)) != 0)	//如果文件夾不存在
	{
		int flag = mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
		if (flag != 0)
		{
			printf("Fail to create directory %s.", dir);
			return OOXML_PARAMETER_ERR;
		}
	}
#endif
	return 0;
}
//遞歸創(chuàng)建文件夾
void mkdirRecursively(const std::string root, const std::string folderPath)
{
	size_t pos = folderPath.find('/');
	std::string subPath;
	if (pos != std::string::npos)
	{
		subPath = folderPath.substr(0, pos);
	}
	else {
		subPath = folderPath;
	}
	if (root == "") {
		if (!subPath.empty())
		{
			if(create_dir(subPath.c_str()) != 0) return ;
			std::string remainingPath = folderPath.substr(pos + 1);
			if (pos != std::string::npos) {
				return 	mkdirRecursively(subPath, remainingPath);
			}
			else {
				return ;
			}
		}
	}
	else {
		std::string subdir = root;
		if (subdir.back() != '/') {
			subdir += "/";
		}
		if (!subPath.empty()){
			std::string current = subdir + subPath;
			if (create_dir(current.c_str()) != 0) return ;
			std::string remainingPath = folderPath.substr(pos + 1);

			if (pos != std::string::npos) {
				return 	mkdirRecursively(current, remainingPath);
			}
			else {
				return ;
			}
		}
	}
	return ;
}

//創(chuàng)建多級文件夾
//如果是文件,則創(chuàng)建文件所占目錄文件夾
void createFolders(std::string rootPath)
{
	std::string::size_type idx = rootPath.find_last_of('/');
	std::string filename = rootPath.substr(idx + 1);
	std::string::size_type pos = filename.find('.');
	if (!filename.empty() && (pos != std::string::npos)) {
		std::string subdirname = rootPath.substr(0, idx + 1);
		//std::cout << subdirname << std::endl;
		mkdirRecursively("", subdirname);
	}
	else{
		//std::cout << rootPath << std::endl;
		mkdirRecursively("", rootPath);
	}
}



void getDirAllFilePath(const char* folderPath, std::vector<std::string>& filePaths)
{
#ifdef  WIN32
	HANDLE hFind;
	WIN32_FIND_DATA findData;
	LARGE_INTEGER size;
	char dirNew[128] = { 0x0 };

	// 向目錄加通配符,用于搜索第一個文件 
	strcpy(dirNew, folderPath);
	strcat(dirNew, "\\*.*");
	hFind = FindFirstFile(dirNew, &findData);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		std::cerr << "無法打開目錄:" << folderPath << std::endl;
		return;
	}

	do
	{
		// 是否是文件夾,并且名稱不為"."或".." 
		//std::cout << findData.dwFileAttributes << "\n";
		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
			&& strcmp(findData.cFileName, ".") != 0
			&& strcmp(findData.cFileName, "..") != 0
			)
		{
			// 將dirNew設(shè)置為搜索到的目錄,并進行下一輪搜索 
			std::string file(findData.cFileName);
			std::string newPath = std::string(folderPath) + "/" + file;
			getFiles(newPath.c_str(), filePaths);
		}
		else if (strcmp(findData.cFileName, ".") == 0 || strcmp(findData.cFileName, "..") == 0) {
			continue;
		}
		else {
			std::string file(findData.cFileName);
			std::string fullPath = std::string(folderPath) + "/" + file;
			filePaths.push_back(fullPath);
		}
	} while (FindNextFile(hFind, &findData));
	FindClose(hFind);
#else
	DIR* dir = opendir(folderPath);
	if (dir == nullptr)
	{
		std::cerr << "無法打開目錄:" << folderPath << std::endl;
		return;
	}

	struct dirent* entry;
	while ((entry = readdir(dir)) != nullptr)
	{
		std::string entryName(entry->d_name);
		if (entryName == "." || entryName == "..")
		{
			continue;
		}

		std::string entryPath(folderPath);
		if (entryPath.back() != '/') { entryPath += "/"; }
		entryPath +=entryName;
		struct stat entryStat;
		if (stat(entryPath.c_str(), &entryStat) == -1)
		{
			std::cerr << "無法獲取文件屬性:" << entryPath << std::endl;
			continue;
		}

		if (S_ISDIR(entryStat.st_mode))
		{
			// 如果是子目錄,則遞歸調(diào)用該函數(shù)獲取子文件夾中的文件路徑
			getFiles(entryPath.c_str(), filePaths);
		}
		else if (S_ISREG(entryStat.st_mode))
		{
			// 如果是文件,則添加到路徑列表中
			filePaths.push_back(entryPath);
		}
	}

	closedir(dir);
#endif
}

到此這篇關(guān)于c++實現(xiàn)解析zip文件的示例代碼的文章就介紹到這了,更多相關(guān)c++解析zip文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++ string常用截取字符串方法

    詳解C++ string常用截取字符串方法

    這篇文章主要介紹了C++ string常用截取字符串方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • C語言詳細分析浮點數(shù)在內(nèi)存中的儲存

    C語言詳細分析浮點數(shù)在內(nèi)存中的儲存

    我們在日常生活中和編程中都會用到小數(shù),比如:3.1415926、29.9、1E10(科學(xué)計數(shù)法也是浮點型)。在C語言中的浮點型類型有:float,double,long double。那么浮點數(shù)在這些浮點型的內(nèi)存之中又是如何儲存的呢,這就是今天我們要分享的
    2022-06-06
  • WIN32程序獲取父進程ID的方法

    WIN32程序獲取父進程ID的方法

    這篇文章主要介紹了WIN32程序獲取父進程ID的方法,在進行windows程序開發(fā)的時候有一定的實用價值,需要的朋友可以參考下
    2014-08-08
  • VSCode配置C/C++并添加非工作區(qū)頭文件的方法

    VSCode配置C/C++并添加非工作區(qū)頭文件的方法

    這篇文章主要介紹了VSCode配置C/C++并添加非工作區(qū)頭文件的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Visual?C++?6.0添加一個對話框的實現(xiàn)步驟

    Visual?C++?6.0添加一個對話框的實現(xiàn)步驟

    VC6.0是微軟公司推出的一款集成開發(fā)環(huán)境,本文主要介紹了Visual?C++?6.0添加一個對話框的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)

    C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)

    這篇文章主要給大家介紹了關(guān)于C++知識點之inline函數(shù)、回調(diào)函數(shù)和普通函數(shù)的相關(guān)使用方法,以及回調(diào)函數(shù)和普通函數(shù)的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-07-07
  • C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解

    C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解

    這篇文章主要介紹了C++命名空間?缺省參數(shù)?const總結(jié)?引用總結(jié)?內(nèi)聯(lián)函數(shù)?auto關(guān)鍵字詳解的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • 基于C++實現(xiàn)日期計算器的詳細教程

    基于C++實現(xiàn)日期計算器的詳細教程

    在現(xiàn)代社會中,計算器已經(jīng)進入了每一個家庭,人們在生活和學(xué)習(xí)中經(jīng)常需要使用到計算器,下面這篇文章主要給大家介紹了關(guān)于基于C++實現(xiàn)日期計算器的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • C語言實現(xiàn)繪制余弦曲線

    C語言實現(xiàn)繪制余弦曲線

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)繪制余弦曲線的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • C++中std::count函數(shù)介紹和使用場景

    C++中std::count函數(shù)介紹和使用場景

    std::count函數(shù)是一個非常實用的算法,它可以幫助我們快速統(tǒng)計給定值在指定范圍內(nèi)的出現(xiàn)次數(shù),本文主要介紹了C++中std::count函數(shù)介紹和使用場景,感興趣的可以了解一下
    2024-02-02

最新評論