我尝试修改(在内存中)zip存档中的一个文件。但我不明白该怎么做
我可以将源文件读入内存,但我不明白下一步该做什么
你能举个例子我怎么能做到这一点
为什么,这是一个简单的 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;
}