2013-07-25 62 views
1

我嘗試修改(在內存中)zip檔案中的一個文件。但我不明白怎麼做了libArchive修改.zip文件中的數據

我能讀到源文件到內存中,但我不明白下一步該怎麼做

你可以給mу例如我怎麼能做到這一點

回答

2

爲什麼,下面是一個簡單的C++ 11例子,替換某個文件並添加一個新文件:

// g++ -std=c++11 -Wall -g -O3 -fno-inline-functions pack.cc -o pack -larchive 
#include <iostream> 
using std::cout; using std::cerr; using std::endl; 
#include <memory> 
using std::shared_ptr; using std::unique_ptr; 
#include <string.h> 
#include <archive.h> // Cygwin's libarchive. http://www.libarchive.org/ 
#include <archive_entry.h> 

int main (int argc, char** argv) { 
    const char* usage = "Usage: pack $in.zip $out.zip $pathToReplace"; 
    const char* inFile = argc > 1 ? argv[1] : nullptr; if (!inFile) {cerr << usage << endl; return 1;} 
    const char* outFile = argc > 2 ? argv[2] : nullptr; if (!outFile) {cerr << usage << endl; return 1;} 
    const char* pathToReplace = argc > 3 ? argv[3] : nullptr; if (!pathToReplace) {cerr << usage << endl; return 1;} 

    shared_ptr<archive> in (archive_read_new(), [inFile](archive* ar) {if (archive_read_finish (ar) != ARCHIVE_OK) cerr << "Error closing " << inFile << endl;}); 
    archive_read_support_format_zip (in.get()); // https://github.com/libarchive/libarchive/wiki/FormatZip 
    int rc = archive_read_open_filename (in.get(), inFile, 65536); 
    if (rc != ARCHIVE_OK) {cerr << "Error opening archive " << inFile << endl; return 1;} 

    shared_ptr<archive> out (archive_write_new(), [outFile](archive* ar) {if (archive_write_finish (ar) != ARCHIVE_OK) cerr << "Error closing " << outFile << endl;}); 
    archive_write_set_format_zip (out.get()); 
    rc = archive_write_open_filename (out.get(), outFile); 
    if (rc != ARCHIVE_OK) {cerr << "Error opening archive " << outFile << endl; return 1;} 

    archive_entry* entry; while (archive_read_next_header (in.get(), &entry) == ARCHIVE_OK) { 
    const char* path = archive_entry_pathname (entry); 
    int64_t size = archive_entry_size (entry); 
    char buf[size]; if (archive_read_data (in.get(), buf, size) != size) {cerr << "Error reading " << path << endl; return 1;} 
    if (strcmp (path, pathToReplace) == 0 && size > 3) {strcpy (buf, "bar"); size = 3;} // Replacing contents of the given file. 
    rc = archive_write_header (out.get(), entry); if (rc != ARCHIVE_OK) {cerr << "Error writing " << path << endl; return 1;} 
    if (archive_write_data (out.get(), buf, size) != size) {cerr << "Error writing " << path << endl; return 1;} 
    } 

    // Add a new file. 
    unique_ptr<archive_entry, void(*)(archive_entry*)> we (archive_entry_new(), archive_entry_free); 
    archive_entry_set_pathname (we.get(), "foo"); 
    archive_entry_set_size (we.get(), 3); 
    archive_entry_set_filetype (we.get(), AE_IFREG); 
    archive_entry_set_perm (we.get(), 0664); 
    rc = archive_write_header (out.get(), we.get()); if (rc != ARCHIVE_OK) {cerr << "Error writing foo" << endl; return 1;} 
    if (archive_write_data (out.get(), "bar", 3) != 3) {cerr << "Error writing foo" << endl; return 1;} 
    return 0; 
} 
+0

這不會修改zip文件中的數據,而是會創建一個帶有不同內容的新zip文件。按照OP的要求,是否有辦法修改壓縮文件中的數據? – josch

+0

@josch我不認爲有可能將壓縮位從一個文件複製到另一個文件而不用'libarchive'重新打包它們。你可能需要一個不太通用的,更加面向ZIP的庫。至於就地修改,我不認爲它是由ZIP格式支持的。 – ArtemGr