我没有阅读足够的手册并运行以下命令
$ zstd -r folder -o output.zst
以下命令给了我一个名为输出的文件
$ unzstd output.zst
输出文件包含串联的文件夹下文件的所有内容。
是否有一些工具或程序可以将单个文件分解为多个原始文件?
这是我唯一的备份文件,我需要备份。
编辑:我真正应该运行的内容(根据这个线程) 是
# for tar version 1.31 and above
$ tar --zstd -cf output.tar.zst folder
# for tar version < 1.31
$ tar --use-compress-program zstd -cf output.tar.zst folder
答案1
我也发布了这个问题zstd github 问题我从中学到了以下内容青色4973。
所有压缩帧都紧接着存储在同一个文件output.zst 中。
虽然至少在理论上有一种方法可以分离每个帧,从而找到每个文件的边界,但另一个问题是这些帧都不包含文件名,也不包含目录树中的位置。所以你最终会得到一堆无名文件。
正确的归档方式是将 zstd 与 tar 结合起来,后者负责保存文件元数据。
目前没有工具或程序可以分离框架。但有人可以使用lz4frame.h
.
默认情况下,CLI 只会将所有帧连续解压缩到同一个解压缩文件中...
...自己编程,...使用
ZSTD_decompressStream()
API。
答案2
这个 Github 问题评论建议使用代码来重现文件(没有文件名和文件夹层次结构)
#undef NDEBUG
#define ZSTD_STATIC_LINKING_ONLY
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <zstd.h>
static uint64_t get_file_size(char const* filename) {
FILE* f = fopen(filename, "rb");
assert(f != NULL);
int ret = fseek(f, 0L, SEEK_END);
assert(ret == 0);
long int const size = ftell(f);
assert(size >= 0);
fclose(f);
return (uint64_t)size;
}
static void read_file(char const* filename, void* buffer, size_t size) {
FILE* f = fopen(filename, "rb");
assert(f != NULL);
size_t const read = fread(buffer, 1, size, f);
assert(read == size);
char tmp;
assert(fread(&tmp, 1, 1, f) == 0);
fclose(f);
}
static size_t decompress_one_frame(char const* inputPtr, char const* inputEnd, char const* outputPrefix, int idx) {
size_t const inputSize = (size_t)(inputEnd - inputPtr);
size_t const compressedSize = ZSTD_findFrameCompressedSize(inputPtr, inputSize);
assert(!ZSTD_isError(compressedSize));
size_t const decompressBound = ZSTD_decompressBound(inputPtr, compressedSize);
assert(decompressBound != ZSTD_CONTENTSIZE_ERROR);
void* const decompressed = malloc(decompressBound);
assert(decompressed != NULL);
size_t const decompressedSize = ZSTD_decompress(decompressed, decompressBound, inputPtr, compressedSize);
assert(!ZSTD_isError(decompressedSize));
size_t const outputFileSize = strlen(outputPrefix) + 11;
char* const outputFile = malloc(outputFileSize);
assert(outputFile != NULL);
{
size_t const written = snprintf(outputFile, outputFileSize, "%s%d", outputPrefix, idx);
assert(written < outputFileSize);
}
{
FILE* f = fopen(outputFile, "wb");
size_t const written = fwrite(decompressed, 1, decompressedSize, f);
assert(written == decompressedSize);
fclose(f);
}
free(outputFile);
free(decompressed);
return compressedSize;
}
int main(int argc, char** argv) {
if (argc != 3) {
fprintf(stderr, "USAGE: %s FILE.zst OUT-PREFIX\n", argv[0]);
fprintf(stderr, "Decompresses a zstd file containing more than one frame to ${OUT-PREFIX}0, ${OUT-PREFIX}1, ...\n");
return 1;
}
char const* const inputFile = argv[1];
char const* const outputPrefix = argv[2];
size_t const inputSize = get_file_size(inputFile);
char* const input = malloc(inputSize);
assert(input != NULL);
read_file(inputFile, input, inputSize);
char const* inputPtr = input;
char const* const inputEnd = input + inputSize;
int idx = 0;
while (inputPtr < inputEnd) {
size_t const compressedSize = decompress_one_frame(inputPtr, inputEnd, outputPrefix, idx);
inputPtr += compressedSize;
++idx;
}
assert(inputPtr == inputEnd);
free(input);
return 0;
}
这个程序将会为你工作。如果将其写入名为 的文件
unzstd.c
,并安装了 libzstd,则可以使用 编译它cc unzstd.c -lzstd -o unzstd
。然后,如果您要解压的文件是input.zst
您可以运行:mkdir output ./unzstd input.zst output/ ls output/
它将为您压缩的每个输入文件创建一个输出文件,按照压缩的顺序,命名为 output/0、output/1 等。因此,您将丢失文件名和目录结构,但您将获得所有内容你的文件回来了。