Я пытаюсь создать tar-файл сжатия gzip. Проблема в том, что выходные данные не являются допустимым файлом сжатия gzip.
Когда я делаю file logfiles.tgz
, он просто говорит: logfiles.tgz: data
и при открытии не показывает никаких файлов/ничего.
const { exec } = require("child_process");
const fs = require("fs");
const outputStream = fs.createWriteStream("../logfiles.tar.gz");
const child = exec(`tar -cz *`, {
cwd: "./logs"
}, (err) => {
if (err) {
console.error(`Could not create archive: ${err}`);
} else {
console.info(`Archive created`);
}
});
child.stdout.pipe(outputStream);
outputStream.on("error", (err) => {
console.error(`Could not write: ${err}`);
});
outputStream.on("finish", () => {
console.info("Write Done");
});
Когда я позволяю tar писать напрямую в файловую систему, все работает нормально:
exec("tar -czf ../logfiles.tar.gz *", {
cwd: "./logs"
}, (err) => {
if (err) {
console.error(`Could not create archive: ${err}`);
} else {
console.info(`Archive created`);
}
});
Как только мне нужен вывод через стандартный вывод в виде потока, я получаю поврежденный/недействительный файл. Я хочу отправить вывод tar через http без необходимости предварительной записи в файловую систему.
Когда я делаю gunzip: logfiles.tar.gz
, он говорит gzip: logfiles.tar.gz: not in gzip format
, что неудивительно, когда file ...
говорит «данные» вместо «gzip».
Почему это недействительный файл, сжатый gzip, когда я использую потоки/стандартный вывод?
Когда я сравниваю оба файла, размер файла потока (почти) в два раза больше:
-rw-rw-r-- 1 marc marc 117936 Apr 26 11:58 logfiles-direct.tar.gz
-rw-rw-r-- 1 marc marc 213813 Apr 26 11:58 logfiles-stream.tar.gz
@JoachimSauer Большое спасибо! Вот и все. Это действительно была кодировка по умолчанию «utf8». Ваше предположение было абсолютно верным.
С помощью комментария Йохаима Зауэра у меня все заработало.
Проблема заключалась в опции кодировки для «exec». Установка значения «буфер» решила проблему.
const child = exec(`tar -cz *`, {
cwd: "./logs",
encoding: "buffer"
});
Работает так, как ожидалось.
Похоже, что-то интерпретирует вывод как текст и пытается закодировать его как UTF-8, что приведет к увеличению размера, но это также бессмысленное/неправильное упражнение. Я недостаточно хорошо знаю API узлов, чтобы сказать вам, что и где, но это мое предположение. Обновлено: очевидно,
exec
имеет параметрencoding
, который вам нужно установить наbinary
, чтобы вывод не интерпретировался как текст.