1

別のアプリケーション (Java で作成) で deflate メソッドを使用してファイルを 1 つの zip ファイルに圧縮する zip ファイルを作成しましたが、「最終更新日」などの情報が現在の日付に変更されていないことを確認し、Ubuntu の既定のアーカイブで解凍すると、マネージャーはそのままです。

ただし、libzip を使用して解凍すると、そのデータが失われます。その動作を回避する方法、またはメタデータの永続性を保証する別のライブラリはありますか?

解凍コード:

void decompress_zip(const std::string& zip, const std::string& out_dir, std::function<void(const std::string&)> fileListener) {
    std::string finput = zip;
    std::string foutput = out_dir;

    if(!boost::filesystem::create_directories(foutput) && !fileExists(foutput))
        throw "Failed to create directory for unzipping";

    foutput += "/tmp.zip";
    if (rename(finput.c_str(), foutput.c_str()))
        throw "Failed to move zip to new dir";
    finput = foutput;

    struct zip *za;
    struct zip_file *zf;
    struct zip_stat sb;
    char buf[100];
    int err;
    int i, len;
    int fd;
    long long sum;

    if ((za = zip_open(finput.c_str(), 0, &err)) == NULL) {
        zip_error_to_str(buf, sizeof(buf), err, errno);
        throw "can't open zip! (" + finput + ")";
    }

    for (i = 0; i < zip_get_num_entries(za, 0); i++) {
        if (zip_stat_index(za, i, 0, &sb) == 0) {
            len = strlen(sb.name);

            if (sb.name[len - 1] == '/') {
                safe_create_dir(sb.name);
            } else {
                zf = zip_fopen_index(za, i, 0);
                if (!zf) {
                    throw "failed to open file in zip! Probably corrupted!!!";
                }

                std::string cFile = out_dir + "/" + std::string(sb.name);
                fd = open(cFile.c_str(), O_RDWR | O_TRUNC | O_CREAT, 0644);
                if (fd < 0) {
                    throw "failed to create output file!";
                }

                sum = 0;
                while (sum != sb.size) {
                    len = zip_fread(zf, buf, 100);
                    if (len < 0) {
                        throw "failed to read file in zip!";
                    }
                    write(fd, buf, len);
                    sum += len;
                }
                close(fd);
                zip_fclose(zf);

                fileListener(cFile);
            }
        }
    }   

    if (zip_close(za) == -1) {
        throw "Failed to close zip archive! " + finput;
    }

    if ( std::remove(foutput.c_str()) )
        throw "Failed to remove temporary zip file! " + foutput;
}
4

1 に答える 1

1

libzipメタデータではなく、データのみを保存すると思います。メタデータが必要な場合は、メタデータを個別に保存する必要があります。

libzipつまり、それ自体ではなく、アーカイブ マネージャー アプリケーションの機能です。

于 2016-07-29T12:52:36.833 に答える