Skip to content

Instantly share code, notes, and snippets.

@loretoparisi
Created November 20, 2021 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loretoparisi/8339cdf44cca0223d976de5cd213d122 to your computer and use it in GitHub Desktop.
Save loretoparisi/8339cdf44cca0223d976de5cd213d122 to your computer and use it in GitHub Desktop.
NodeJS Unarchive tar gz file
const { Duplex } = require('stream'); // Native Node Module
function bufferToStream(myBuffer) {
let tmp = new Duplex();
tmp.push(myBuffer);
tmp.push(null);
return tmp;
}
async function tarStream() {
const zlib = require('zlib');
const tar = require('tar-stream');
const { promisify } = require('util');
const writeFile = promisify(fs.writeFile);
const extract = tar.extract();
const gunzip = zlib.createGunzip();
var chunks = [];
extract.on('entry', function (header, stream, next) {
stream.on('data', function (chunk) {
chunks.push(chunk);
});
stream.on('end', function () {
next();
});
stream.resume();
});
extract.on('finish', async function () {
if (chunks && chunks.length) {
const myReadableStream = bufferToStream(Buffer.from(chunks));
myReadableStream
.pipe(fs.createWriteStream(destPath))
.on('close', async function () {
consoleLogger.info("wrote %s", destPath);
})
.on('error', (error) => {
consoleLogger.warn("gunzip error:%@", error.toString());
})
}
})
.on('error', (error) => {
consoleLogger.warn("gunzip error:%@", error.toString());
})
fs.createReadStream(tmpPath)
.pipe(gunzip)
.pipe(extract)
}//tarStream
async function decompressStream() {
const decompress = require('decompress');
const decompressTargz = require('decompress-targz');
const stream = fs.createReadStream(tmpPath);
const files = await decompressTargz()(stream);
if (files && files.length && files[0].path) {
// { data: Buffer, path: String }
const myReadableStream = bufferToStream(files[0].data);
myReadableStream
.pipe(fs.createWriteStream(destPath))
.on('close', async function () {
consoleLogger.info("wrote %s", destPath);
})
.on('error', (error) => {
consoleLogger.warn("gunzip error:%@", error.toString());
})
}
}//decompressStream
async function decompress() {
const decompress = require('decompress');
const decompressTargz = require('decompress-targz');
decompress(tmpPath, os.tmpdir(), {
plugins: [
decompressTargz()
]
}).then(() => {
console.log('Files decompressed');
});
}//decompress
async function tarspawn() {
return new Promise(async (resolve, reject) => {
var spawn = require('child_process').spawn;
var tar = spawn('tar', ['-xzvf', tmpPath, '-C', './']);
tar.on('exit', function (code) {
if (code === 0) {
return resolve(tmpPath);
} else {
var error = new Error();
error.code=code;
return reject(error);
}
});
});
}//tarspawn
@loretoparisi
Copy link
Author

NOTE. for binary files archives exceeding 2147483647 bytes, the only working solution is tarspawn. See here for more detalis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment