<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用libzip壓縮文件和文件夾

      簡單說說自己遇到的坑:

      1. 分清楚三個組件:zlib、minizip和libzip。zlib是底層和最基礎的C庫,用于使用Deflate算法壓縮和解壓縮文件流或者單個文件,但是如果要壓縮文件夾就很麻煩,主要是不知道如何歸檔,在zip內部形成對應的目錄。這時就需要用更高級別的庫,也就是minizip或libzip。

      2. minizip、libzip隨著版本迭代接口一直變化,我連續使用了通義千問、文心一言、gemini三個AI,基本上沒給出能使用的代碼,主要是函數接口總是不對,或者參數多了或者少了。像這種情況就不要再參考AI給出的答案了,趕緊翻官方文檔才是正經。

      3. minizip和libzip都是基于zlib實現的,都嘗試使用過,感覺還是libzip的接口設計更清晰一點,官方文檔說明也還不錯。

      4. 壓縮文件夾的功能需要借助于操作文件系統的庫來組織zip內部的歸檔目錄,我這里使用的是C++17的std::filesystem。

      具體代碼實現如下:

      #include <zip.h>
      
      #include <filesystem>
      #include <fstream>
      #include <iostream>
      
      using namespace std;
      
      void CompressFile2Zip(std::filesystem::path unZipFilePath,
                            const char* relativeName, zip_t* zipArchive) {
        std::ifstream file(unZipFilePath, std::ios::binary);
        file.seekg(0, std::ios::end);
        size_t bufferSize = file.tellg();
        char* bufferData = (char*)malloc(bufferSize);
      
        file.seekg(0, std::ios::beg);
        file.read(bufferData, bufferSize);
      
        //第四個參數如果非0,會自動托管申請的資源,直到zip_close之前自動銷毀。
        zip_source_t* source =
            zip_source_buffer(zipArchive, bufferData, bufferSize, 1);
      
        if (source) {
          if (zip_file_add(zipArchive, relativeName, source, ZIP_FL_OVERWRITE) < 0) {
            std::cerr << "Failed to add file " << unZipFilePath
                      << " to zip: " << zip_strerror(zipArchive) << std::endl;
            zip_source_free(source);
          }
        } else {
          std::cerr << "Failed to create zip source for " << unZipFilePath << ": "
                    << zip_strerror(zipArchive) << std::endl;
        }
      }
      
      void CompressFile(std::filesystem::path unZipFilePath,
                        std::filesystem::path zipFilePath) {
        int errorCode = 0;
        zip_t* zipArchive = zip_open(zipFilePath.generic_u8string().c_str(),
                                     ZIP_CREATE | ZIP_TRUNCATE, &errorCode);
        if (zipArchive) {
          CompressFile2Zip(unZipFilePath, unZipFilePath.filename().string().c_str(),
                           zipArchive);
      
          errorCode = zip_close(zipArchive);
          if (errorCode != 0) {
            zip_error_t zipError;
            zip_error_init_with_code(&zipError, errorCode);
            std::cerr << zip_error_strerror(&zipError) << std::endl;
            zip_error_fini(&zipError);
          }
        } else {
          zip_error_t zipError;
          zip_error_init_with_code(&zipError, errorCode);
          std::cerr << "Failed to open output file " << zipFilePath << ": "
                    << zip_error_strerror(&zipError) << std::endl;
          zip_error_fini(&zipError);
        }
      }
      
      void CompressDirectory2Zip(std::filesystem::path rootDirectoryPath,
                                 std::filesystem::path directoryPath,
                                 zip_t* zipArchive) {
        if (rootDirectoryPath != directoryPath) {
          if (zip_dir_add(zipArchive,
                          std::filesystem::relative(directoryPath, rootDirectoryPath)
                              .generic_u8string()
                              .c_str(),
                          ZIP_FL_ENC_UTF_8) < 0) {
            std::cerr << "Failed to add directory " << directoryPath
                      << " to zip: " << zip_strerror(zipArchive) << std::endl;
          }
        }
      
        for (const auto& entry : std::filesystem::directory_iterator(directoryPath)) {
          if (entry.is_regular_file()) {
            CompressFile2Zip(
                entry.path().generic_u8string(),
                std::filesystem::relative(entry.path(), rootDirectoryPath)
                    .generic_u8string()
                    .c_str(),
                zipArchive);
          } else if (entry.is_directory()) {
            CompressDirectory2Zip(rootDirectoryPath, entry.path().generic_u8string(),
                                  zipArchive);
          }
        }
      }
      
      void CompressDirectory(std::filesystem::path directoryPath,
                             std::filesystem::path zipFilePath) {
        int errorCode = 0;
        zip_t* zipArchive = zip_open(zipFilePath.generic_u8string().c_str(),
                                     ZIP_CREATE | ZIP_TRUNCATE, &errorCode);
        if (zipArchive) {
          CompressDirectory2Zip(directoryPath, directoryPath, zipArchive);
      
          errorCode = zip_close(zipArchive);
          if (errorCode != 0) {
            zip_error_t zipError;
            zip_error_init_with_code(&zipError, errorCode);
            std::cerr << zip_error_strerror(&zipError) << std::endl;
            zip_error_fini(&zipError);
          }
        } else {
          zip_error_t zipError;
          zip_error_init_with_code(&zipError, errorCode);
          std::cerr << "Failed to open output file " << zipFilePath << ": "
                    << zip_error_strerror(&zipError) << std::endl;
          zip_error_fini(&zipError);
        }
      }
      
      int main() {
        //壓縮文件
        //CompressFile("C:/Data/Builder/Demo/view.tmp", "C:/Data/Builder/Demo/view.zip");
      
        //壓縮文件夾
        CompressDirectory("C:/Data/Builder/Demo", "C:/Data/Builder/Demo.zip");
      
        return 0;
      }
      

      關于使用的libzip,有以下幾點值得注意:

      1. libzip壓縮的zip內部的文件名默認采用UTF-8編碼。
      2. libzip要求使用正斜杠 ('/') 作為目錄分隔符。
      3. libzip操作不同的zip線程安全,操作同一個zip線程不安全。
      4. zip_source_buffer這個函數的接口的第四個參數如果非0,會自動托管申請的資源。官方文檔提到需要保證傳入zip_source_buffer的數據資源需要保證跟zip_source_t一樣的聲明周期,但是筆者經過測試,正確的行為應該是傳入zip_source_buffer的數據資源需要保證調用zip_close之前都有效,否則就有問題。
      posted @ 2024-07-12 23:12  charlee44  閱讀(2009)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 在线涩涩免费观看国产精品 | 欧洲美熟女乱又伦免费视频| 成人性生交大片免费看r老牛网站 中文字幕一区二区三区四区五区 久久久久久毛片免费播放 | 四虎精品国产永久在线观看| 一区二区三区岛国av毛片| 欧美在线观看www| 亚洲av成人午夜福利| 真人作爱免费视频| 国产精品激情av在线播放| 宾阳县| 国产成人精品亚洲午夜麻豆| 亚洲成av人片无码天堂下载| 国产999久久高清免费观看| 精品人妻码一区二区三区| 国产亚欧女人天堂AV在线| 亚洲成人av高清在线| 国产精品熟妇视频国产偷人| 日韩东京热一区二区三区| 成人免费亚洲av在线| 日本一区二区三区18岁| 亚洲av午夜成人片| 成人网站免费观看永久视频下载 | 成人毛片100免费观看| 欧洲精品色在线观看| 国产成人无码AV片在线观看不卡| 中文成人在线| 亚洲国产成人精品女人久| 亚洲情A成黄在线观看动漫尤物 | 国产免费福利网站| 国产一区二区三区我不卡| 精品黑人一区二区三区| 日韩三级一区二区在线看| 亚洲精品日韩精品久久| 午夜不卡欧美AAAAAA在线观看| 久久久久蜜桃精品成人片公司| 成人国产乱对白在线观看| 东京热高清无码精品| 南郑县| 国产精品入口中文字幕| 日本一区二区三区在线 |观看| 国产精品13页|