当前位置: 首页 > news >正文

使用POCO库进行ZIP压缩和解压

使用POCO库进行ZIP压缩和解压

POCO C++ Libraries提供了一个ZIP模块,可以方便地进行文件和数据流的压缩与解压操作。下面我将介绍如何使用POCO的ZIP模块进行这些操作。

1. 基本ZIP文件操作

压缩文件/目录到ZIP

#include <Poco/Zip/Compress.h>
#include <Poco/File.h>
#include <Poco/Path.h>
#include <iostream>
#include <fstream>

void compressToZip(const std::string& source, const std::string& zipFile)
{
    try {
        std::ofstream out(zipFile, std::ios::binary);
        Poco::Zip::Compress c(out, true);
        
        Poco::File f(source);
        if (f.isDirectory()) {
            c.addRecursive(f, Poco::Zip::ZipCommon::CL_MAXIMUM, f.path());
        } else {
            c.addFile(f, f.path());
        }
        
        c.close(); // 必须调用close()完成ZIP文件
        out.close();
        
        std::cout << "Successfully created ZIP file: " << zipFile << std::endl;
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
// compressToZip("my_folder", "output.zip");
// compressToZip("file.txt", "file.zip");

解压ZIP文件

#include <Poco/Zip/Decompress.h>
#include <Poco/Path.h>
#include <iostream>
#include <fstream>

void decompressZip(const std::string& zipFile, const std::string& destDir)
{
    try {
        std::ifstream in(zipFile, std::ios::binary);
        Poco::Zip::Decompress d(in, Poco::Path(destDir));
        d.decompressAllFiles();
        in.close();
        
        std::cout << "Successfully extracted ZIP file to: " << destDir << std::endl;
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
// decompressZip("archive.zip", "extracted_files");

2. 流数据压缩和解压

POCO还提供了对数据流进行压缩和解压的功能,使用的是Poco::Zip::ZipStream

压缩数据流

#include <Poco/Zip/ZipStream.h>
#include <Poco/Zip/ZipArchive.h>
#include <Poco/Zip/ZipLocalFileHeader.h>
#include <iostream>
#include <sstream>
#include <fstream>

void compressStreamToZip(const std::string& outputFile)
{
    try {
        std::ofstream out(outputFile, std::ios::binary);
        Poco::Zip::ZipOutputStream zipOut(out);
        
        // 添加第一个文件到ZIP
        zipOut.putNextEntry("file1.txt");
        std::string content1 = "This is the content of file1.txt";
        zipOut << content1;
        
        // 添加第二个文件到ZIP
        zipOut.putNextEntry("subdir/file2.txt");
        std::string content2 = "This is file2.txt in a subdirectory";
        zipOut << content2;
        
        zipOut.close();
        out.close();
        
        std::cout << "Successfully created ZIP from streams: " << outputFile << std::endl;
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
// compressStreamToZip("stream_output.zip");

解压数据流

#include <Poco/Zip/ZipStream.h>
#include <Poco/Zip/ZipArchive.h>
#include <iostream>
#include <fstream>
#include <sstream>

void decompressZipToStreams(const std::string& zipFile)
{
    try {
        std::ifstream in(zipFile, std::ios::binary);
        Poco::Zip::ZipArchive archive(in);
        
        for (auto it = archive.headerBegin(); it != archive.headerEnd(); ++it) {
            const Poco::Zip::ZipLocalFileHeader& header = *it;
            if (header.isFile()) {
                std::cout << "Extracting: " << header.getFileName() << std::endl;
                
                std::istream* pStream = archive.findStream(header.getFileName());
                if (pStream) {
                    std::stringstream content;
                    Poco::StreamCopier::copyStream(*pStream, content);
                    std::cout << "Content:\n" << content.str() << "\n" << std::endl;
                }
            }
        }
        
        in.close();
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
// decompressZipToStreams("stream_output.zip");

3. 内存中的ZIP操作

在内存中创建ZIP

#include <Poco/Zip/ZipStream.h>
#include <Poco/Zip/ZipArchive.h>
#include <iostream>
#include <sstream>

void createZipInMemory()
{
    try {
        std::stringstream outStream(std::ios::in | std::ios::out | std::ios::binary);
        Poco::Zip::ZipOutputStream zipOut(outStream);
        
        // 添加文件到内存中的ZIP
        zipOut.putNextEntry("memory_file.txt");
        std::string content = "This file was created in memory";
        zipOut << content;
        
        zipOut.close();
        
        // 获取ZIP数据
        std::string zipData = outStream.str();
        std::cout << "Created ZIP in memory, size: " << zipData.size() << " bytes" << std::endl;
        
        // 可以将zipData保存到文件或通过网络发送
        // std::ofstream("memory.zip", std::ios::binary) << zipData;
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
// createZipInMemory();

从内存中读取ZIP

#include <Poco/Zip/ZipArchive.h>
#include <iostream>
#include <sstream>
#include <vector>

void readZipFromMemory(const std::vector<char>& zipData)
{
    try {
        std::stringstream inStream(std::ios::in | std::ios::out | std::ios::binary);
        inStream.write(zipData.data(), zipData.size());
        
        Poco::Zip::ZipArchive archive(inStream);
        
        for (auto it = archive.headerBegin(); it != archive.headerEnd(); ++it) {
            const Poco::Zip::ZipLocalFileHeader& header = *it;
            if (header.isFile()) {
                std::cout << "Found file in memory ZIP: " << header.getFileName() << std::endl;
                
                std::istream* pStream = archive.findStream(header.getFileName());
                if (pStream) {
                    std::stringstream content;
                    Poco::StreamCopier::copyStream(*pStream, content);
                    std::cout << "Content:\n" << content.str() << std::endl;
                }
            }
        }
    } catch (Poco::Exception& e) {
        std::cerr << "Error: " << e.displayText() << std::endl;
    }
}

// 使用示例
/*
std::vector<char> zipData = ...; // 从文件或网络获取的ZIP数据
readZipFromMemory(zipData);
*/

注意事项

  1. 确保在项目中正确链接POCO的Foundation和Zip库。
  2. 压缩或解压大文件时,考虑使用缓冲区以提高性能。
  3. 处理ZIP文件时要注意路径安全问题,特别是解压来自不可信源的ZIP文件时。
  4. 所有示例代码都需要包含相应的POCO头文件,并处理可能的异常。

以上示例展示了POCO库中ZIP模块的基本用法,你可以根据实际需求进行调整和扩展。

相关文章:

  • VSCode CLine 插件自定义配置使用 Claude 3.7 模型进行 AI 开发
  • 深入理解 Linux PATH 环境变量:配置与优化!!!
  • Crossmint 与 Walrus 合作,将协议集成至其跨链铸造 API 中
  • WPF ObjectDataProvider
  • Dify插件安装与使用教程
  • 基于SSM框架的房屋租赁小程序开发与实现
  • OpengGL教程(七)---摄像机
  • 在Ubuntu服务器上安装Docker(支持Ubuntu 20.04/22.04等版本):
  • 道路运输安全员岗位事项有哪些?
  • HBuilderX中uni-app打包Android(apk)全流程超详细打包
  • 建设“大数据智慧招商平台”,助力园区突破招商瓶颈!
  • 2025 年“认证杯”数学中国数学建模网络挑战赛 C题 化工厂生产流程的预测和控制
  • 03--Deepseek服务器部署与cjson解析
  • 魔改chromium源码——新增自定义变量到windows属性
  • 前端学习10—Ajax
  • iOS应用开发指南
  • 力扣第272场周赛
  • UniAD:自动驾驶的统一架构 - 创新与挑战并存
  • 生物化学笔记:医学免疫学原理14 感染免疫 感染免疫的机制+病原体的免疫逃逸机制
  • LeetCode算法题(Go语言实现)_40
  • 网站体验调查问卷怎么做/超级seo助手
  • 简要说明网站建设的步骤/公司网站建设哪个好
  • 开发网站公司排行榜/百度知道网页版登录入口
  • 高端网站开发制作/搜索引擎优化师工资
  • 大连鼎信网站建设公司/百度登录个人中心
  • 个人网站主页设计/全国疫情最新情报